Księga bankowa
Część sekcji Programowanie obiektowe ścieżki Swift w Coddy. Lekcja 57 z 57.
Wyzwanie
TrudnyZbuduj mały bank. Account to klasa z właściwościami id, owner i private(set) var balance oraz metodami deposit(_:) i withdraw(_:), które zgłaszają błędy BankError.invalidAmount (poniżej 1) i BankError.insufficient(id:). Checking pozwala na debet w wysokości 100 (saldo może spaść do -100); Savings odrzuca wypłaty, które spowodowałyby ujemne saldo, dodaje odsetki w wysokości 1% (zaokrąglone w dół) w monthEnd() i pozwala na maksymalnie 2 wypłaty w miesiącu (BankError.limit(id:)), a licznik jest zerowany przez monthEnd(). Account.monthEnd() nic nie robi. Klasa Bank przechowuje konta według identyfikatora i ma metodę transfer(from:to:amount:), która wypłaca i wpłaca środki albo w razie niepowodzenia nie wykonuje żadnych zmian.
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 błąd (invalid amount, insufficient funds in 2, withdrawal limit on 2, no account 9), a na końcu wypisuje każde konto posortowane według identyfikatora jako 1 ada checking: -20.
Umieść swój kod w plikach BankError.swift, Account.swift, Checking.swift, Savings.swift i Bank.swift. Plik main.swift zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
// Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
var input: [String] = []
while let line = readLine() { input.append(line) }
let bank = Bank()
for cmd in input {
let p = cmd.split(separator: " ").map(String.init)
do {
switch p[0] {
case "open":
let id = Int(p[2])!
bank.accounts[id] = p[1] == "savings" ? Savings(id: id, owner: p[3]) : Checking(id: id, owner: p[3])
case "dep": try bank.account(Int(p[1])!).deposit(Int(p[2])!)
case "wd": try bank.account(Int(p[1])!).withdraw(Int(p[2])!)
case "tr": try bank.transfer(from: Int(p[1])!, to: Int(p[2])!, amount: Int(p[3])!)
default: bank.accounts.values.forEach { $0.monthEnd() }
}
print("ok")
} catch BankError.invalidAmount {
print("invalid amount")
} catch BankError.insufficient(let id) {
print("insufficient funds in \(id)")
} catch BankError.limit(let id) {
print("withdrawal limit on \(id)")
} catch BankError.noAccount(let id) {
print("no account \(id)")
} catch {
print("error")
}
}
for id in bank.accounts.keys.sorted() {
let a = bank.accounts[id]!
print("\(a.id) \(a.owner) \(a.kind): \(a.balance)")
}
Wszystkie lekcje w sekcji Programowanie obiektowe
1Klasy i obiekty
Praca z plikamiDefiniowanie klasMetody i selfInicjalizatoryKlasy są referencjamiPowtórzenie — karta biblioteczna4Hermetyzacja
Kontrola dostępuTylko do odczytu z zewnątrzOchrona stanuInicjalizatory, które mogą zawieśćPodsumowanie — konto bankowe7Polimorfizm i typy generyczne
PolimorfizmRzutowanie typówFunkcje generyczneTypy generycznePodsumowanie – kalkulator kształtów2Struktury i typy wartościowe
StrukturySemantyka wartościMetody modyfikująceStruktura czy klasaPodsumowanie – element inwentarza5Dziedziczenie
PodklasyPrzesłanianie metodInicjalizatory i superfinal i hierarchiePodsumowanie — hierarchia pracowników8Standardowe protokoły
CustomStringConvertibleEquatableComparableHashablePodsumowanie — własne sortowanie11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książekPoćwicz samodzielnie: Edytor online Swift