Menu
Coddy logo textTech

銀行台帳

CoddyのSwiftジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 57/57。

challenge icon

チャレンジ

難しい

小さな銀行を作成してください。Accountはid、owner、private(set) var balanceを持つクラスであり、BankError.invalidAmount(1未満)とBankError.insufficient(id:)をスローするメソッドdeposit(_:)およびwithdraw(_:)を備えます。Checkingでは100の当座貸越が可能です(残高は-100まで下がることがあります)。Savingsは残高が負になる引き出しを拒否し、monthEnd()で1%の利息(切り捨て)を加算し、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プレイグラウンド