Menu
Coddy logo textTech

Банковский реестр

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

challenge icon

Задание

Сложно

Создайте небольшой банк.

  • 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}")
}

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

Потренируйтесь самостоятельно: Песочница Kotlin