自定义访问器
本课属于 Coddy Kotlin 学习旅程的“面向对象编程”单元。第 7 课,共 57 课。
每个 Kotlin 属性都有一个getter(获取器),每个 var 也都有一个setter(设置器)。默认情况下,它们会读取和写入存储的值。自定义 getter 会在每次读取时计算值:
class Rectangle(var width: Int, var height: Int) {
val area: Int
get() = width * height
}在 main 中:
val r = Rectangle(3, 4)
println(r.area)
r.width = 10
println(r.area)输出:
12
40每当属性被赋值时,自定义 setter 都会运行代码。在其中,value 是赋给属性的值,field 是属性背后存储的值,也就是后备字段:
class Thermostat {
var target = 20
set(value) {
field = value.coerceIn(10, 30)
}
}在 main 中:
val t = Thermostat()
t.target = 42
println(t.target)
t.target = 18
println(t.target)输出:
30
18在访问器中,使用 field,而不是属性名:在 target 的 setter 中写 target = value 会再次调用 setter,造成无限递归:
var target = 20
set(value) {
// target = value // 会再次调用这个 setter:导致无限递归
field = value // 存储这个值
}setter 也是响应更改的地方,例如可以统计或记录更改:
class Player(name: String) {
var changes = 0
private set
var name = name
set(value) {
field = value.trim()
changes++
}
}在 main 中:
val p = Player("ada")
p.name = " Ada "
p.name = "Ada L."
println("${p.name} after ${p.changes} changes")输出:
Ada L. after 2 changes挑战
简单完成类 Circle(radius: Double)。radius 是一个 var,其 setter 会将负值存储为 0。添加只读属性 diameter 和 area(π r²,使用 Math.PI),并添加 label,它会返回 r=2.0 d=4.0 a=12.57,其中面积四舍五入到小数点后两位("%.2f".format(area))。
提供的代码会逐行读取一个半径,打印 label,然后将最后一个圆的半径加倍,再次打印 label,因此这些值必须随半径变化。
你的代码写在 Circle.kt 中。Main.kt 中包含提供的输入/输出代码,不能编辑。
亲手试试
fun main() {
// 提供的输入/输出代码:保持原样
val input = generateSequence(::readLine).toList()
var last = Circle(0.0)
for (line in input) {
last = Circle(line.toDouble())
println(last.label)
}
last.radius *= 2
println(last.label)
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Kotlin 在线编辑器