gpt4 book ai didi

inheritance - 错误或功能 : Kotlin allows to change 'val' to 'var' in inheritance

转载 作者:IT老高 更新时间:2023-10-28 13:30:09 30 4
gpt4 key购买 nike

我刚刚开始探索 Kotlin 语言。我正在为继承、var&val 和副作用而苦苦挣扎。

如果我用 val x 声明一个特征 A 并在 AImpl 中覆盖 x ,则可以将其覆盖为 var(参见下面的代码)。令人惊讶的是, A 中的 print() 方法会受到 x 重新分配的影响,即使 xA。这是错误还是功能?

代码:

trait A {
fun print() {
println("A.x = $x")
}

val x : Int;
}

class AImpl(x : Int) : A {
override var x = x; // seems like x can be overriden as `var`
}

fun main(args: Array<String>) {

val a = AImpl(2)

a.print() // A.x = 2

a.x = 3; // x can be changed

// even though print() is defined in trait A
// where x is val it prints x = 3
a.print() // A.x = 3

}

我知道如果我明确定义 a 类型为 A 则不允许更改 x:

val a = AImpl(2) : A
a.x = 3 // ERROR: value x cannot be reassigned

但正如第一种情况所示,继承可能会导致副作用,这在 A 中显然不是有意的。如何保护值不被继承更改?

最佳答案

您可以使您的 val final,即完全禁止覆盖它。如果你在一个类中定义了一个val,它默认是final

另外,如果你需要用 var 覆盖 val,但不希望 setter 公开,你可以这样说:

override var x = 1
private set

var 覆盖 val 是一项功能。这相当于添加了一个 set-method,而在父类(super class)中只有一个 get-method。这对于实现一些模式(例如只读接口(interface))相当重要。

除了将其设为 final 之外,没有办法“保护”你的 val 不被覆盖,因为 val > 并不意味着“不可变引用”,而仅仅是“只读属性”。换句话说,当你的 trait A 声明一个 val 时,这意味着 通过一个 A 类型的引用客户端无法编写此 val,没有其他保证,或者确实可能。

附:分号在 Kotlin 中是可选的,可以完全省略它们

关于inheritance - 错误或功能 : Kotlin allows to change 'val' to 'var' in inheritance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22820505/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com