Menu
CoddyTech

Sổ cái ngân hàng

Thuộc phần Lập trình hướng đối tượng trong hành trình Kotlin của Coddy. Bài học 57 trên 57.

challenge icon

Thử thách

Khó

Xây dựng một ngân hàng nhỏ.

  • BankError(message) là một lớp sealed kế thừa Exception, với các lớp con InvalidAmount (invalid amount), Insufficient(id) (insufficient funds in 2), WithdrawalLimit(id) (withdrawal limit on 2) và NoAccount(id) (no account 9).
  • Account(id, owner) là lớp trừu tượng. Mọi nơi đều có thể đọc balance, nhưng chỉ các lớp tài khoản mới có thể thay đổi thuộc tính này. deposit(amount) và withdraw(amount) ném InvalidAmount nếu số tiền nhỏ hơn 1, còn withdraw ném Insufficient khi số dư sẽ giảm xuống dưới lowestBalance của tài khoản. Lớp này khai báo kind trừu tượng và phương thức mở monthEnd(), phương thức này không làm gì cả.
  • Checking cho phép thấu chi xuống đến -100. Savings không bao giờ có số dư dưới 0, cho phép tối đa 2 lần rút tiền mỗi tháng (WithdrawalLimit) và trong monthEnd(), cộng thêm lãi suất 1% (làm tròn xuống) rồi đặt lại số lần rút tiền.
  • Bank có open(kind, id, owner), account(id) (ném NoAccount), transfer(from, to, amount), phương thức này tìm cả hai tài khoản trước rồi mới rút tiền và gửi tiền, monthEnd() áp dụng cho mọi tài khoản và accounts() sắp xếp tài khoản theo id.

Code được cung cấp đọc các lệnh open checking 1 ada, open savings 2 bo, dep 1 100, wd 2 30, tr 1 2 50 hoặc month, in ra ok hoặc thông báo lỗi, rồi cuối cùng in ra mọi tài khoản theo định dạng 1 ada checking: -20.

Code của bạn nằm trong các tệp BankError.kt, InvalidAmount.kt, Insufficient.kt, WithdrawalLimit.kt, NoAccount.kt, Account.kt, Checking.kt, Savings.kt và Bank.kt. Main.kt chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.

Tự làm thử

fun main() {
    // Đoạn code đầu vào/đầu ra đã được cung cấp: giữ nguyên
    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}")
}

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Playground Kotlin