mih*_*iho 18 inheritance side-effects kotlin
我刚开始探索Kotlin语言.我正在努力进行遗传,变异和副作用.
如果我宣布一个特质A
与val x
和覆盖x
在AImpl
它可以覆盖它var
(见下面的代码).令人惊讶的是,该print()
方法A
受到重新分配的影响,x
即使它x
是一个值A
.这是一个错误还是一个功能?
码:
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
}
Run Code Online (Sandbox Code Playgroud)
我知道如果我明确定义a
类型A
,则不允许更改x
:
val a = AImpl(2) : A
a.x = 3 // ERROR: value x cannot be reassigned
Run Code Online (Sandbox Code Playgroud)
但是,正如第一个案例所示,遗传可能会导致明显无意的副作用A
.如何保护值不被继承更改?
And*_*lav 29
你可以制作你的val
final
,即完全禁止覆盖它.如果val
在类中定义a ,则final
默认为.
另外,如果你需要重写一个val
有var
,但不希望的setter是公共的,你可以这么说:
override var x = 1
private set
Run Code Online (Sandbox Code Playgroud)
val
用a 覆盖a var
是一个功能.它相当于添加set方法,而在超类中只有一个get方法.这对于实现某些模式非常重要,例如只读接口.
没有办法以val
一种允许改变突变而不是改变突变的方式"保护"你的被覆盖final
,因为val
这并不意味着"不可变引用",而只是"只读属性".换句话说,当你的特征A
声明a时val
,这意味着通过类型A
的引用,客户端不能写这个val
,没有其他保证,或者确实可能.
PS Semicolons在Kotlin中是可选的,可以完全省略它们
归档时间: |
|
查看次数: |
3294 次 |
最近记录: |