Банковская система
Часть раздела Объектно-ориентированное программирование путешествия по Java на Coddy — урок 85 из 87.
В рамках этого испытания вам предстоит создать Банковскую систему, которая моделирует реальные финансовые операции, используя принципы ООП.
Ваша система должна поддерживать различные типы счетов, такие как SavingsAccount и CheckingAccount, оба из которых расширяют базовый класс Account. Каждый тип счета обладает уникальным поведением: сберегательные счета могут приносить проценты, в то время как текущие счета могут иметь защиту от овердрафта.
Подумайте о том, как моделировать транзакции. Интерфейс, такой как Transactable, мог бы определять методы для deposit() и withdraw(). Рассмотрите возможность использования пользовательских исключений, таких как InsufficientFundsException, для корректной обработки недопустимых операций.
Класс Bank может управлять несколькими счетами и клиентами, демонстрируя композицию. Вы могли бы применить паттерн Factory для создания различных типов счетов или использовать паттерн Observer для уведомления клиентов об изменениях в счете.
Сосредоточьтесь на инкапсуляции для защиты конфиденциальных данных, таких как балансы и номера счетов, и используйте полиморфизм для единообразной обработки различных типов счетов.
Задание
ЛегкоДавайте создадим полноценную банковскую систему, которая продемонстрирует ваше мастерство в принципах ООП! Вы создадите систему с различными типами счетов, обработкой транзакций и правильным управлением исключениями — и все это будет организовано в нескольких файлах.
Вы организуете свой код в семи файлах:
Transactable.java: Создайте интерфейс, который определяет контракт для финансовых операций. Он должен объявлять методыdeposit(double amount)иwithdraw(double amount), оба возвращают логическое значение для индикации успеха.InsufficientFundsException.java: Создайте пользовательское исключение, которое расширяетException. Конструктор должен принимать сумму попытки снятия и текущий баланс, создавая сообщение в формате"Insufficient funds: attempted %.2f, available %.2f".Account.java: Создайте абстрактный базовый класс, представляющий любой банковский счет. Включите приватные поля дляaccountNumber(String) иbalance(double), конструктор, который инициализирует оба поля, соответствующие геттеры, защищенный (protected) сеттер для баланса (чтобы подклассы могли его изменять) и абстрактный методgetAccountType(), который возвращает String. Реализуйте методgetDetails(), который возвращает"%s (%s): $%.2f", где баланс отформатирован до 2 знаков после запятой.SavingsAccount.java: Создайте класс, который расширяетAccountи реализуетTransactable. Добавьте приватное поле дляinterestRate(double). Конструктор принимает accountNumber, начальный баланс и interestRate. РеализуйтеgetAccountType(), чтобы он возвращал"Savings". Дляdeposit()добавьте сумму к балансу и верните true. Дляwithdraw(), если сумма превышает баланс, верните false; в противном случае вычтите сумму и верните true. Добавьте методapplyInterest(), который увеличивает баланс наbalance * interestRate(ставка хранится как дробь, поэтому0.05означает 5%).CheckingAccount.java: Создайте класс, который расширяетAccountи реализуетTransactable. Добавьте приватное поле дляoverdraftLimit(double). Конструктор принимает accountNumber, начальный баланс и overdraftLimit. РеализуйтеgetAccountType(), чтобы он возвращал"Checking". Дляdeposit()добавьте сумму и верните true. Дляwithdraw()разрешите снятие, если сумма меньше или равна балансу плюс overdraftLimit; верните false, если она превышает этот лимит.Bank.java: Создайте класс, который управляет счетами с помощью ArrayList. Включите методы:addAccount(Account account)- добавляет счет в банкfindAccount(String accountNumber)- возвращает Account или null, если счет не найденtransfer(String fromAccount, String toAccount, double amount)- переводит деньги между счетами, выбрасываяInsufficientFundsException, если на исходном счете недостаточно средств. При успехе возвращает"Transferred $%.2f from %s to %s"getTotalDeposits()- возвращает сумму балансов всех счетов
Main.java: Постройте свою банковскую систему! Вы получите строку команд, разделенных запятыми:SAVINGS:accountNumber:balance:interestRateCHECKING:accountNumber:balance:overdraftLimitDEPOSIT:accountNumber:amountWITHDRAW:accountNumber:amountTRANSFER:fromAccount:toAccount:amountINTEREST:accountNumber
Обработайте каждую команду и выведите:
- SAVINGS/CHECKING:
"Account created: " + accountNumber - DEPOSIT:
"Deposited $%.2f to %s%n" - WITHDRAW:
"Withdrew $%.2f from %s%n"при успехе или"Withdrawal failed: " + accountNumber - TRANSFER: Выведите сообщение об успехе или
"Transfer failed: " + e.getMessage() - INTEREST:
"Interest applied to " + accountNumber
После всех команд выведите
"--- Bank Summary ---", затем детали каждого счета (используяgetDetails()) и, наконец,"Total deposits: $%.2f%n", отформатированные до 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Обратите внимание, как чековый счет позволяет снять 600 долларов, несмотря на то, что на балансе всего 500 долларов — это работа защиты от овердрафта! Сберегательный счет получает 5% годовых на свой баланс после перевода. Эта задача объединяет наследование, интерфейсы, полиморфизм, пользовательские исключения и инкапсуляцию в реалистичное банковское приложение!
Попробуйте сами
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: Разделите входную строку по запятой, чтобы получить отдельные команды
// TODO: Обработайте каждую команду:
// - SAVINGS:accountNumber:balance:interestRate -> Создайте SavingsAccount, выведите "Account created: [accountNumber]"
// - CHECKING:accountNumber:balance:overdraftLimit -> Создайте CheckingAccount, выведите "Account created: [accountNumber]"
// - DEPOSIT:accountNumber:amount -> Внесите депозит и выведите "Deposited $[amount] to [accountNumber]"
// - WITHDRAW:accountNumber:amount -> Снимите средства и выведите сообщение об успехе или "Withdrawal failed: [accountNumber]"
// - TRANSFER:fromAccount:toAccount:amount -> Выполните перевод и выведите сообщение об успехе или "Transfer failed: [exception message]"
// - INTEREST:accountNumber -> Примените проценты и выведите "Interest applied to [accountNumber]"
// TODO: После всех команд выведите "--- Bank Summary ---"
// TODO: Выведите детали каждого счета, используя getDetails()
// TODO: Выведите "Total deposits: $[total]", отформатировав до 2 знаков после запятой
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово thisМетодыПоля (атрибуты)Метод-конструкторПерегрузка конструкторовИтоги — Простой калькулятор4Наследование
Основы наследования (extends)Ключевое слово superПереопределение методов (@Override)Цепочка конструкторовКласс ObjectОдиночное и многоуровневое наследованиеПочему нет множественного наследования классовИтоги — Иерархия сотрудников7Специальные методы и класс Object
Метод toString()equals() и hashCode()Метод clone()compareTo() и ComparableИнтерфейс ComparatorПовторение — Кастомная сортировка2Модификаторы доступа и инкапсуляция
Обзор уровней доступаМетоды геттеры и сеттерыСокрытие данныхКлючевое слово finalИтоги — Менеджер банковского счета5Полиморфизм
Основы перегрузки методовПереопределение методов (Run-Time)Upcasting и DowncastingОператор instanceofАбстрактные классы и методыИтоги: Калькулятор фигур8Продвинутые концепции ООП
Композиция против наследованияАгрегация против композицииВнутренние, вложенные и анонимные классыEnums и методы перечисленийRecords (Java 16+)Sealed-классы (Java 17+)11Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн BuilderПаттерн ObserverПаттерн Strategy14Финальные испытания
Платформа онлайн-обученияБанковская системаРазработка игрового персонажаСервис аренды транспорта3Свойства класса и статические члены
Переменные экземпляра и статические переменныеСтатические методыСтатические блокиКонстанты (static final)Итоги: Счетчик и утилиты6Интерфейсы и абстрактные классы
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовDefault и Static методы в интерфейсахАбстрактные классы vs ИнтерфейсыФункциональные интерфейсыИтоги — Платежная система9Обобщения
Введение в обобщенияОбобщенные классыОбобщенные методыОграниченные параметры типаСимволы подстановки (Wildcards: ?, extends, super)Итоги — Обобщенный контейнер12Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»Паттерн «Итератор»