微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

jvm – 为什么我们不能将val属性覆盖为带有get而没有初始化的var?

我刚刚开始学习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对象采用空值).

一个解决方案是使用这样的自定义setter –

override var x: Int // Now you can leave it uninitialized
            get() {
                return super.x * (super.x * 10)
            }
            set(value) {
                // nothing happens
            }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐