Menu
CoddyTech

图书与会员

本课属于 Coddy Kotlin 学习旅程的“面向对象编程”单元。第 50 课,共 57 课。

在这个项目中,你将搭建图书馆系统的核心。Library 类会接收命令,每行一条,并逐条回复。经过 5 个步骤,它将学会添加书籍和成员、借出和归还书籍、搜索目录以及打印报告:

ADD_BOOK 1 Dune
JOIN ada
BORROW ada 1
RETURN ada 1
SEARCH dune
REPORT

这个数据模型使用了本单元讲过的内容。Book 和 Member 各自位于单独的文件中。所有地方都可以读取图书的 borrower,但只能通过 lendTo 和 giveBack 修改;成员对象会以只读的 List 暴露其借阅记录的 ID。图书馆用两个私有映射保存它们,因此只有图书馆自身的方法可以修改它们:

class Book(val id: Int, val title: String) {
    var borrower: String? = null
        private set
    val isAvailable: Boolean
        get() = borrower == null
    fun lendTo(name: String) { borrower = name }
}

在 main 中:

val books = mutableMapOf<Int, Book>()
books[1] = Book(1, "Dune")
books.getValue(1).lendTo("ada")
println("${books.getValue(1).isAvailable} ${books.getValue(1).borrower}")

输出:

false ada

handle(line) 会拆分命令,并根据第一个单词使用 when。每个分支都会以 List<String> 的形式返回回复,因此像 REPORT 这样的命令可以回复多行内容,而提前执行 return 则会返回拒绝信息。书名可能包含空格,因此它是 id 后面的所有内容:

在 main 中:

val p = "ADD_BOOK 7 The Hobbit".split(" ")
val id = p[1].toInt()
val title = p.drop(2).joinToString(" ")
println("$id: $title")

输出:

7: The Hobbit
challenge icon

挑战

简单

完成 Library.handle(line),处理前两个命令:

  • ADD_BOOK <id> <title>:存储一本新的可借阅图书,并回复 added book 1: Dune;如果该 id 已被占用,则回复 book 1 exists。
  • JOIN <name>:添加一名成员,并回复 welcome ada;如果该名称已存在,则回复 ada is already a member。

提供的代码会将每一行输入传给 library.handle(line),并将每条返回的回复单独打印在一行上。成员名称由单个小写单词组成,图书 id 是整数,输入中仅包含目前介绍的命令。对于其他命令,回复 unknown command。

你的代码写在 Book.kt、Member.kt 和 Library.kt 中。Main.kt 包含提供的输入/输出代码,不能编辑。

亲手试试

fun main() {
    // 提供的输入输出代码:保持原样。
    val input = generateSequence(::readLine).toList()
    val library = Library()
    for (line in input) {
        for (reply in library.handle(line)) println(reply)
    }
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Kotlin 在线编辑器