我刚刚开始学习Kotlin . 我想知道为什么我们不能在重写的val属性上使用 get()
方法作为var而不初始化它 . 但是当被覆盖为 val
时,它可以在没有初始化的情况下工作 .
open class Foo {
val y = 21
open val x: Int
get() {
return 10 * y
}
}
class Bar : Foo() {
override var x: Int = super.x * 10 //If overridden as val works without initialisation
get() {
return super.x * (super.x * 10)
}
}
fun main(args: Array<String>) {
val bar: Bar = Bar()
println("${bar.x}")
}
如果我没有在 Bar
类中初始化 x
,则会给出编译器错误 Property must be initialised
. 但是当我打印 bar.x
时,它打印从重写的getter计算的值,但不打印初始化的getter .
2 回答
这种行为是由于Kotlin中backing fields的概念 . 正如文档中所写 -
由于重写的属性
x
现在是一个var,它具有如下所示的setter的默认实现 .因此,在声明var时,必须使用某个值初始化支持字段,因为Kotlin中没有默认值的概念(例如,未初始化的Java对象采用空值) .
另一个解决方案是使用这样的自定义setter -
如果没有以某种方式定义的两个访问器(
get
和set
),则无法定义var
属性 .放置初始化程序(
var x: Int = ...
)时,会生成一个支持字段,并设置一个设置支持字段的默认设置器 . 初始化程序的替代方法是提供自定义setter:请参阅:语言参考中的Properties and Fields