错误或特征:Kotlin允许在inheritance中将“val”更改为“var”

我刚开始探索Kotlin语言。 我正在努力inheritance,var和val和副作用

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

码:

 trait A { fun print() { println("Ax = $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) { val a = AImpl(2) a.print() // Ax = 2 ax = 3; // x can be changed // even though print() is defined in trait A // where x is val it prints x = 3 a.print() // Ax = 3 } 

我意识到这样一个事实,即如果我明确定义atypesA ,不允许更改x

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

但是,正如第一个案例所显示的那样,inheritance可能导致副作用,这在A中显然不是有意A 。 如何保护值不被inheritance改变?

2 Solutions collect form web for “错误或特征:Kotlin允许在inheritance中将“val”更改为“var””

你可以让你的val final ,即禁止压倒一切。 如果你在一个类中定义了一个val ,那么默认是final的。

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

 override var x = 1 private set 

var覆盖val 是一个特性 。 这相当于添加一个set方法,而在超类中只有一个get方法。 这在实现一些模式(如只读接口)时非常重要。

没有办法“保护”你的val不被重写,而是允许改变变化,而不是final ,因为val并不意味着“不变的参考”,而只是“只读属性”。 换句话说,当你的特质A声明一个val ,这意味着通过typesA引用客户不能写这个val ,没有其他的保证是有意的,或者确实是可能的。

PS分号在Kotlin中是可选的,完全可以省略

我会认为这是一个function,因为更改VAL到VAR施加较弱的使用限制, 并且不能破坏任何超类代码 。 可见性修改器可以观察到类似的情况:

 trait A { protected fun print() { ... } } class AImpl: A { public override fun print() { ... } } 

在这个例子中,可见性限制也被一个子类放宽,尽管有些人正在把这种技术看作一个反模式。

如何保护值不被inheritance改变?

在kotlin中,你可以明确地定义是否有任何特定的类成员可以被使用open修饰符的子类覆盖。 然而,在特征上,所有成员都是默认开放的。 解决的办法是用类替换特质,所以你可以控制inheritance:

 abstract class A { fun print() { ... } val x : Int = 2; } class AImpl(x : Int) : A() { override var x = x // compilation error } 
  • 在EditText上处理Enter键(Kotlin,Android)
  • Kotlin透明属性解析器?
  • Kotlin中未解决的参考异步
  • 无法使用Android Gradle插件3.0.1解决assembleAndroidTest任务的依赖关系
  • 我怎样才能抑制未经检查的强制性警告?
  • Kotlin中的异步匿名函数? (lambdaexpression式)
  • Android工作室kotlin插件错误
  • 在Kotlin中的正则expression式匹配
  • 当expression式中删除Kotlin的中断
  • 如何用Kotlin就地过滤列表?
  • 标准的二进制maxBy函数
  • Kotlin language will be the best programming language for Android.