Банковский реестр
Часть раздела Объектно-ориентированное программирование путешествия по Kotlin на Coddy. Урок 57 из 57.
Задание
СложноСоздайте небольшой банк.
BankError(message)— запечатанный класс, расширяющийException, с подклассамиInvalidAmount(invalid amount),Insufficient(id)(insufficient funds in 2),WithdrawalLimit(id)(withdrawal limit on 2) иNoAccount(id)(no account 9).Account(id, owner)— абстрактный класс. Егоbalanceможно читать отовсюду, а изменять — только из классов счетов.deposit(amount)иwithdraw(amount)выбрасываютInvalidAmountдля сумм меньше 1, аwithdrawвыбрасываетInsufficient, если баланс опустится нижеlowestBalanceсчёта. В нём объявлены абстрактное свойствоkindи открытый методmonthEnd(), который ничего не делает.Checkingдопускает овердрафт до -100. БалансSavingsникогда не опускается ниже 0, допускается не более 2 снятий в месяц (WithdrawalLimit), а вmonthEnd()добавляются проценты в размере 1% (с округлением вниз) и сбрасывается счётчик снятий.Bankсодержитopen(kind, id, owner),account(id)(выбрасываетNoAccount),transfer(from, to, amount), который сначала находит оба счёта, а затем выполняет снятие и пополнение,monthEnd()для каждого счёта иaccounts(), возвращающий счета, отсортированные по id.
Предоставленный код считывает команды open checking 1 ada, open savings 2 bo, dep 1 100, wd 2 30, tr 1 2 50 или month, выводит ok или сообщение об ошибке, а в конце — каждый счёт в формате 1 ada checking: -20.
Ваш код должен находиться в файлах BankError.kt, InvalidAmount.kt, Insufficient.kt, WithdrawalLimit.kt, NoAccount.kt, Account.kt, Checking.kt, Savings.kt и Bank.kt. В Main.kt находится предоставленный код ввода/вывода, и его нельзя изменять.
Попробуйте сами
fun main() {
// Предоставленный код ввода/вывода: оставьте его как есть
val input = generateSequence(::readLine).toList()
val bank = Bank()
for (cmd in input) {
val p = cmd.split(" ")
try {
when (p[0]) {
"open" -> bank.open(p[1], p[2].toInt(), p[3])
"dep" -> bank.account(p[1].toInt()).deposit(p[2].toInt())
"wd" -> bank.account(p[1].toInt()).withdraw(p[2].toInt())
"tr" -> bank.transfer(p[1].toInt(), p[2].toInt(), p[3].toInt())
else -> bank.monthEnd()
}
println("ok")
} catch (e: BankError) {
println(e.message)
}
}
for (a in bank.accounts()) println("${a.id} ${a.owner} ${a.kind}: ${a.balance}")
}
Все уроки раздела Объектно-ориентированное программирование
1Классы и объекты
Работа с файламиОпределение классовПервичные конструкторыБлоки init и валидацияВторичные конструкторыПовторение — читательский билет4Наследование
Открытые классы и подклассыПереопределение членовsuper и конструкторыАбстрактные классыПовторение — каталог сотрудников7Специальные классы
Классы данныхКлассы перечисленийЗапечатанные иерархииequals, hashCode, toStringПовторение — трекер заказов10Паттерны проектирования. Часть 2
Делегирование с помощью byПаттерн декораторПаттерн строительПаттерн состояние2Свойства и инкапсуляция
Пользовательские аксессорыМодификаторы видимостиПриватные сеттерыlazy и lateinitПовторение — банковский счёт5Интерфейсы
Объявление интерфейсовМетоды по умолчаниюМножественные интерфейсыИнтерфейсы как типыПовторение — способы оплаты8Обобщения
Обобщённые функцииОбобщённые классыОграничения типовВариативность с in и outПовторение — очередь с приоритетом11Проект: Управление библиотекой
Книги и читателиВыдача книг3Объекты и компаньоны
Объявления объектовОбъекты-компаньоныКонстанты с constОбъектные выраженияПовторение — билетная касса6Полиморфизм
Динамическая диспетчеризацияПроверка типов и умные приведения типовwhen с типамиФункции-расширенияПовторение — смотритель зоопарка9Паттерны проектирования. Часть 1
Паттерн «Одиночка»Фабричный паттернПаттерн «Наблюдатель»Паттерн «Стратегия»Потренируйтесь самостоятельно: Песочница Kotlin