在kotlin的类中,对于一个var修饰的变量来说,默认会自动带上setter和getter的方法,
例如
class Cat(weightParam: Int) {
var weight: Int = weightParam
}
在其他的地方中,可以通过以下的方法来获取与修改
fun testCat() {
val cat = Cat(20)
//20
println(cat.weight)
cat.weight = 40
//40
println(cat.weight)
cat.weight = -10
//-10
println(cat.weight)
}
对于一些值来说,需要对setter做一定的限制,例如猫的重量是不能为负值的,这就需要我们自定义setter方法或者getter
因此对Cat的weight需要重写,如下
class Cat(weightParam: Int) {
var weight: Int = weightParam
set(value) {
if (value > 0) {
field = value
}
}
}
经过修改后的,同样的测试函数结果如下:
fun testCat() {
val cat = Cat(20)
//20
println(cat.weight)
cat.weight = 40
//40
println(cat.weight)
cat.weight = -10
//40
println(cat.weight)
}
可以对属性进行有效的保护
注意的是,在自定义setter中,赋值时需要使用的是field,而不是weight:

setter是一个名为set的函数,我们将其放在属性声明下方。
setter有一个参数,通常将其命名为value,这是即将准备赋给属性的新值。
在上面的实例中,仅当value大于0时,才会更新weight属性的值。
如果尝试将weight属性更新为小于或等于0的值,则setter会停止更新属性值。
setter通过field标识更新weight属性值。
field指的是属性的支持字段,你可以将其视为对属性的底层值的引用。
在getter和setter中使用field代替属性名称很重要,因为这样可以阻止你陷入无限循环中。
例如,当运行以下setter代码时,系统将会尝试更新weight属性,这会导致setter一次又一次地被调用:
每次你尝试设置新的属性值时,属性的setter都将会被调用。例如,下面的代码将会调用weight属性的setter,并且75将会作为参数传递给setter:如前所述,编写自定义的getter和setter意味着你可以保护属性,避免其被滥用。使用自定义的getter可以控制在请求属性值时的返回值,而自定义的setter允许你在赋值之前进行验证。
参考自《Head First Kotlin 》第4章 如何自定义setter
网友评论