我刚开始学习Kotlin。我想知道为什么我们不能在不初始化的情况下将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计算的值。
3条答案
按热度按时间vngu2lb81#
如果没有以某种方式定义两个访问器(
get
和set
),则无法定义var
属性。当你放置一个初始化器(
var x: Int = ...
)时,会生成一个支持字段和一个设置支持字段的默认setter。一个替代初始化器的方法是提供一个自定义setter:请参阅:语言参考中的属性和字段
ix0qys7i2#
这种行为是由于Kotlin中支持字段的概念。
如果属性使用至少一个存取子的预设实作,或如果自订存取子透过字段识别项指涉它,则会产生属性的支援字段。
由于被覆盖的属性
x
现在是一个var,因此它有一个setter的默认实现,如下所示。因此,当声明一个var时,你必须用某个值初始化支持字段,因为在Kotlin中没有默认值的概念(例如,未初始化的Java对象取空值)。
另一个解决方案是使用这样的自定义setter-
z2acfund3#
转换为java
因此瓦尔属性未创建setter