图书与会员
本课属于 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 adahandle(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挑战
简单完成 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)
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Kotlin 在线编辑器