Rejestr bankowy
Część sekcji Programowanie obiektowe ścieżki Kotlin w Coddy. Lekcja 57 z 57.
Wyzwanie
TrudnyZbuduj mały bank.
BankError(message)jest zapieczętowaną klasą rozszerzającąException, z podklasamiInvalidAmount(invalid amount),Insufficient(id)(insufficient funds in 2),WithdrawalLimit(id)(withdrawal limit on 2) iNoAccount(id)(no account 9).Account(id, owner)jest klasą abstrakcyjną. Wartośćbalancemożna odczytać z dowolnego miejsca, a zmieniać tylko w klasach kont.deposit(amount)iwithdraw(amount)zgłaszająInvalidAmountdla kwot mniejszych niż 1, awithdrawzgłaszaInsufficient, gdy saldo spadłoby poniżej wartościlowestBalancedanego konta. Deklaruje abstrakcyjną właściwośćkindoraz otwartą funkcjęmonthEnd(), która nic nie robi.Checkingpozwala na debet do -100. Saldo kontaSavingsnigdy nie spada poniżej 0, pozwala na najwyżej 2 wypłaty miesięcznie (WithdrawalLimit) i w funkcjimonthEnd()nalicza 1% odsetek (zaokrąglając w dół) oraz zeruje licznik wypłat.Bankma funkcjeopen(kind, id, owner),account(id)(zgłaszaNoAccount),transfer(from, to, amount), która najpierw wyszukuje oba konta, a następnie wykonuje wypłatę i wpłatę,monthEnd()dla każdego konta orazaccounts(), która zwraca konta posortowane według id.
Dostarczony kod odczytuje polecenia open checking 1 ada, open savings 2 bo, dep 1 100, wd 2 30, tr 1 2 50 lub month, wypisuje ok albo treść błędu, a na końcu wypisuje każde konto jako 1 ada checking: -20.
Twój kod umieść w plikach BankError.kt, InvalidAmount.kt, Insufficient.kt, WithdrawalLimit.kt, NoAccount.kt, Account.kt, Checking.kt, Savings.kt i Bank.kt. Main.kt zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
fun main() {
// Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
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}")
}
Wszystkie lekcje w sekcji Programowanie obiektowe
1Klasy i obiekty
Praca z plikamiDefiniowanie klasKonstruktory główneBloki init i walidacjaKonstruktory dodatkowePodsumowanie — karta biblioteczna4Dziedziczenie
Klasy otwarte i podklasyNadpisywanie składowychsuper i konstruktoryKlasy abstrakcyjnePodsumowanie – katalog pracowników7Klasy specjalne
Klasy danychKlasy wyliczenioweHierarchie zapieczętowaneequals, hashCode, toStringPodsumowanie — śledzenie zamówień10Wzorce projektowe, część 2
Delegowanie za pomocą byWzorzec dekoratoraWzorzec budowniczegoWzorzec stanu2Właściwości i hermetyzacja
Własne akcesoryModyfikatory widocznościPrywatne setterylazy i lateinitPowtórka – konto bankowe5Interfejsy
Deklarowanie interfejsówMetody domyślneWiele interfejsówInterfejsy jako typyPowtórzenie – metody płatności8Typy generyczne
Funkcje generyczneKlasy generyczneOgraniczenia typówKowariancja i kontrawariancja: in i outPodsumowanie — kolejka priorytetowa11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książekPoćwicz samodzielnie: Edytor online Kotlin