Menu
Coddy logo textTech

Банковская система

Часть раздела Объектно-ориентированное программирование путешествия по Java на Coddy. Урок 85 из 87.

В этом задании вам предстоит создать Banking System, моделирующую реальные финансовые операции с использованием принципов ООП.

Ваша система должна обрабатывать различные типы account, такие как SavingsAccount и CheckingAccount, оба расширяющие базовый Account class. Каждый тип account обладает уникальным поведением: сберегательные счета могут приносить проценты, а расчетные счета могут иметь защиту от овердрафта.

Подумайте о том, как моделировать транзакции. Интерфейс, такой как Transactable, может определять методы для deposit() и withdraw(). Рассмотрите возможность использования пользовательских исключений, таких как InsufficientFundsException, чтобы корректно обрабатывать недопустимые операции.

Класс Bank может управлять несколькими accounts и клиентами, демонстрируя композицию. Можно применить паттерн Factory для создания различных типов account или использовать паттерн Observer, чтобы уведомлять клиентов об изменениях account.

Сосредоточься на инкапсуляции, чтобы защитить конфиденциальные данные, такие как балансы и номера счетов, и используй полиморфизм для единообразной обработки разных типов счетов.

challenge icon

Задание

Легко

Давайте создадим полноценную банковскую систему, которая продемонстрирует ваше владение принципами ООП! Вы создадите систему с различными типами счетов, обработкой транзакций и корректным управлением исключениями: всё будет организовано в нескольких файлах.

Вы организуете код в семи файлах:

  • Transactable.java: Создайте интерфейс, определяющий контракт для финансовых операций. Он должен объявлять методы deposit(double amount) и withdraw(double amount), оба возвращающие boolean для обозначения успешного выполнения.
  • InsufficientFundsException.java: Создайте пользовательское исключение, расширяющее Exception. Конструктор должен принимать attempted сумму снятия и текущий balance, создавая сообщение в формате Insufficient funds: attempted [amount], available [balance].
  • Account.java: Создайте абстрактный базовый класс, представляющий любой банковский счет. Добавьте private поля accountNumber (String) и balance (double), constructor, инициализирующий оба поля, соответствующие геттеры, protected setter для balance (чтобы подклассы могли изменять его), а также абстрактный метод getAccountType(), возвращающий String. Реализуйте метод getDetails(), который возвращает "[accountNumber] ([accountType]): $[balance]", при этом balance должен быть отформатирован до 2 десятичных знаков.
  • SavingsAccount.java: Создайте класс, который расширяет Account и реализует Transactable. Добавьте private поле interestRate (double). Constructor принимает accountNumber, начальный balance и interestRate. Реализуйте getAccountType(), возвращающий "Savings". В deposit() добавьте amount к balance и верните true. В withdraw(), если amount превышает balance, верните false; в противном случае вычтите amount и верните true. Добавьте метод applyInterest(), который увеличивает balance на balance * interestRate (ставка хранится как дробь, поэтому 0.05 означает 5%).
  • CheckingAccount.java: Создайте класс, который расширяет Account и реализует Transactable. Добавьте private поле overdraftLimit (double). Constructor принимает accountNumber, начальный balance и overdraftLimit. Реализуйте getAccountType(), возвращающий "Checking". В deposit() добавьте amount и верните true. В withdraw() разрешите снятие, если amount меньше или равен balance плюс overdraftLimit; верните false, если amount превышает этот лимит.
  • Bank.java: Создайте класс, который управляет счетами с помощью ArrayList. Добавьте методы:
    • addAccount(Account account) — добавляет счет в банк
    • findAccount(String accountNumber) — возвращает Account или null, если счет не найден
    • transfer(String fromAccount, String toAccount, double amount) — переводит деньги между счетами, выбрасывая InsufficientFundsException, если на исходном счете недостаточно средств. При успешном выполнении верните "Transferred $[amount] from [fromAccount] to [toAccount]"
    • getTotalDeposits() — возвращает сумму всех балансов счетов
  • Main.java: Создайте свою банковскую систему! Вы получите разделенную запятыми строку команд:
    • SAVINGS:accountNumber:balance:interestRate
    • CHECKING:accountNumber:balance:overdraftLimit
    • DEPOSIT:accountNumber:amount
    • WITHDRAW:accountNumber:amount
    • TRANSFER:fromAccount:toAccount:amount
    • INTEREST:accountNumber

    Обработайте каждую команду и выведите:

    • SAVINGS/CHECKING: Account created: [accountNumber]
    • DEPOSIT: Deposited $[amount] to [accountNumber]
    • WITHDRAW: Withdrew $[amount] from [accountNumber] при успешном выполнении или Withdrawal failed: [accountNumber]
    • TRANSFER: выведите сообщение об успешном выполнении или Transfer failed: [exception message]
    • INTEREST: Interest applied to [accountNumber]

    После выполнения всех команд выведите --- Bank Summary ---, затем сведения о каждом счете (с помощью getDetails()) и, наконец, Total deposits: $[total], отформатированное до 2 десятичных знаков.

Вы получите один входной параметр: разделенную запятыми строку команд.

Например, если на вход подается SAVINGS:SAV001:1000.00:0.05,CHECKING:CHK001:500.00:200.00,DEPOSIT:SAV001:250.00,WITHDRAW:CHK001:600.00,TRANSFER:SAV001:CHK001:100.00,INTEREST:SAV001, результатом будет:

Account created: SAV001
Account created: CHK001
Deposited $250.00 to SAV001
Withdrew $600.00 from CHK001
Transferred $100.00 from SAV001 to CHK001
Interest applied to SAV001
--- Bank Summary ---
SAV001 (Savings): $1207.50
CHK001 (Checking): $0.00
Total deposits: $1207.50

Обратите внимание, как checking account позволяет снять $600, несмотря на наличие только $500 balance: это overdraft protection в действии! savings account получает 5% interest от своего balance после перевода. В этом challenge объединены inheritance, interfaces, polymorphism, custom exceptions и encapsulation в реалистичном банковском приложении!

Попробуйте сами

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        
        // TODO: Создать экземпляр Bank
        
        // TODO: Разделить input по запятой, чтобы получить отдельные команды
        
        // TODO: Обработать каждую команду:
        // - SAVINGS:accountNumber:balance:interestRate -> Create SavingsAccount, print "Account created: [accountNumber]"
        // - CHECKING:accountNumber:balance:overdraftLimit -> Create CheckingAccount, print "Account created: [accountNumber]"
        // - DEPOSIT:accountNumber:amount -> Внести депозит и вывести "Deposited $[amount] to [accountNumber]"
        // - WITHDRAW:accountNumber:amount -> Withdraw and print success or "Withdrawal failed: [accountNumber]"
        // - TRANSFER:fromAccount:toAccount:amount -> Выполнить перевод и вывести успех или "Transfer failed: [exception message]"
        // - INTEREST:accountNumber -> Apply interest and print "Interest applied to [accountNumber]"
        
        // TODO: После всех команд вывести "--- Bank Summary ---"
        
        // TODO: Вывести детали каждого счёта, используя getDetails()
        
        // TODO: Print "Total deposits: $[total]" formatted to 2 decimal places
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Java