银行账簿
本课属于 Coddy Swift 学习旅程的“面向对象编程”单元。第 57 课,共 57 课。
挑战
困难构建一个小型银行。Account 是一个类,包含 id、owner 和 private(set) var balance,以及方法 deposit(_:) 和 withdraw(_:)。当金额小于 1 时,这些方法会抛出 BankError.invalidAmount;余额不足时会抛出 BankError.insufficient(id:)。Checking 允许透支 100(余额最低可到 -100);Savings 拒绝会使余额变成负数的取款,在 monthEnd() 时增加 1% 利息(向下取整),并且每月最多允许取款 2 次(BankError.limit(id:)),在 monthEnd() 时重置取款次数。Account.monthEnd() 不执行任何操作。Bank 类按 id 存储账户,并提供 transfer(from:to:amount:),用于取款并存款,失败时不做任何更改。
提供的代码会读取以下命令:open checking 1 ada、open savings 2 bo、dep 1 100、wd 2 30、tr 1 2 50 或 month;然后输出 ok 或错误信息(invalid amount、insufficient funds in 2、withdrawal limit on 2、no account 9),最后按 id 排序输出每个账户,格式为 1 ada checking: -20。
你的代码写在 BankError.swift、Account.swift、Checking.swift、Savings.swift 和 Bank.swift 中。main.swift 包含提供的输入/输出代码,不能编辑。
亲手试试
// 提供的输入/输出代码:保持原样。
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)")
}
面向对象编程中的所有课
自己练习: Swift 在线编辑器