对象表达式
本课属于 Coddy Kotlin 学习旅程的“面向对象编程”单元。第 15 课,共 57 课。
对象表达式会在需要的地方创建一个匿名类的一次性对象。它的写法是 object : Type { ... },通常用于实现接口。接口会列出方法,但不说明它们如何工作;第 5 章会深入讲解接口:
interface Greeter {
fun greet(name: String): String
}在 main 中:
val polite = object : Greeter {
override fun greet(name: String) = "Good morning, $name."
}
println(polite.greet("Ada"))输出:
Good morning, Ada.对象声明只存在一次。对象表达式会在其代码每次运行时求值,每次运行都会创建一个新对象。它可以读取和更改周围的局部变量:
interface Counter {
fun next(): Int
}
fun counterFrom(start: Int): Counter {
var current = start
return object : Counter {
override fun next() = current++
}
}在 main 中:
val a = counterFrom(10)
val b = counterFrom(1)
println("${a.next()} ${a.next()} ${b.next()}")输出:
10 11 1一种常见用法是将行为交给库函数。sortedWith 接受一个 Comparator,它是一个接口,其方法 compare(a, b) 在 a 排在前面时返回负数,平局时返回零,否则返回正数:
在 main 中:
val words = listOf("kiwi", "fig", "banana", "apple")
val byLength = object : Comparator<String> {
override fun compare(a: String, b: String) = a.length - b.length
}
println(words.sortedWith(byLength))输出:
[fig, kiwi, apple, banana]不带超类型的对象表达式可以将几个值组合到一个局部对象中;它的属性可以在同一个函数中使用。如果接口只有一个方法,lambda 通常比对象表达式更简洁。当需要多个方法或需要保存一些状态时,适合使用对象表达式。
val size = object {
val width = 3
val height = 4
}
println(size.width * size.height) // 12
val byLength = Comparator<String> { a, b -> a.length - b.length } // lambda 表达式形式挑战
简单接口 Validator 有一个方法 check(text),文本未通过时会返回错误消息,通过时则返回 null。请完成函数 rules(minLength),让它按以下顺序返回三个通过对象表达式创建的验证器:文本至少包含 minLength 个字符(too short)、包含一个数字(needs a digit),且不包含空格(no spaces allowed)。
提供的代码会读取最小长度,然后逐行读取密码。它会输出 ok,或者输出该密码的所有错误消息,并用 ; 连接。
你的代码要写在 Rules.kt 和 Validator.kt 中。Main.kt 中是提供的输入输出代码,不能编辑。
亲手试试
fun main() {
// 提供的输入输出代码:保持原样。
val input = generateSequence(::readLine).toList()
val checks = rules(input[0].toInt())
for (password in input.drop(1)) {
val problems = checks.mapNotNull { it.check(password) }
println(if (problems.isEmpty()) "ok" else problems.joinToString("; "))
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Kotlin 在线编辑器