Registro bancario
Fa parte della sezione Programmazione orientata agli oggetti del percorso Swift di Coddy. Lezione 57 di 57.
Sfida
DifficileCrea una piccola banca. Account è una classe con id, owner e un private(set) var balance, e i metodi deposit(_:) e withdraw(_:) che generano BankError.invalidAmount (inferiore a 1) e BankError.insufficient(id:). Checking consente uno scoperto di 100 (il saldo può scendere fino a -100); Savings rifiuta i prelievi che porterebbero il saldo in negativo, aggiunge un interesse dell'1% (arrotondato per difetto) in monthEnd() e consente al massimo 2 prelievi al mese (BankError.limit(id:)), azzerati da monthEnd(). Account.monthEnd() non fa nulla. La classe Bank memorizza i conti in base all'id e dispone di transfer(from:to:amount:), che preleva e deposita oppure, in caso di errore, non fa nulla.
Il codice fornito legge i comandi open checking 1 ada, open savings 2 bo, dep 1 100, wd 2 30, tr 1 2 50 o month, stampa ok oppure l'errore (invalid amount, insufficient funds in 2, withdrawal limit on 2, no account 9) e infine stampa ogni conto ordinato per id come 1 ada checking: -20.
Il tuo codice va inserito in BankError.swift, Account.swift, Checking.swift, Savings.swift e Bank.swift. main.swift contiene il codice fornito per l'input/output e non può essere modificato.
Provalo tu
// Codice di input/output fornito: lascialo così com'è
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)")
}
Tutte le lezioni di Programmazione orientata agli oggetti
1Classi e oggetti
Lavorare con i fileDefinire le classiMetodi e selfInizializzatoriLe classi sono riferimentiRiepilogo - Tessera della biblioteca4Incapsulamento
Controllo degli accessiSola lettura dall’esternoProteggere lo statoInizializzatori che possono fallireRiepilogo - Conto bancario7Polimorfismo e tipi generici
PolimorfismoCasting dei tipiFunzioni genericheTipi genericiRipasso - Calcolatore di forme2Struct e tipi valore
Le structSemantica dei valoriMetodi mutantiStruct o classeRiepilogo - Articolo di inventario5Ereditarietà
SottoclassiSovrascrivere i metodiInizializzatori e superfinal e gerarchieRiepilogo - Gerarchia dei dipendenti8Protocolli standard
CustomStringConvertibleEquatableComparableHashableRiepilogo - Ordinamento personalizzato11Progetto: Gestione della biblioteca
Libri e utentiPrestito dei libriEsercitati da solo: Playground Swift