我刚刚开始学习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,则会给出编译器错误.必须初始化属性.但是当我打印bar.x时,它打印从重写的getter计算的值,但不打印初始化的getter.
解决方法
这种行为是由于Kotlin的
backing fields概念.正如文档中所写 –
A backing field will be generated for a property if it uses the default implementation of at least one of the accessors,or if a custom accessor references it through the field identifier.
由于重写的属性x现在是var,因此它具有如下所示的setter的默认实现.
override var x: Int = super.x * 10 get() { return super.x * (super.x * 10) } set(value) { field = value }
因此,在声明var时,必须使用某个值初始化支持字段,因为Kotlin中没有默认值的概念(例如,未初始化的Java对象采用空值).
override var x: Int // Now you can leave it uninitialized get() { return super.x * (super.x * 10) } set(value) { // Nothing happens }