为什么不能在scala中覆盖可变变量?

mog*_*gli 15 inheritance overriding scala

为什么不能在scala中覆盖可变变量?

class Abs(var name: String){
}

class AbsImpl(override var name: String) extends Abs(name){
}
Run Code Online (Sandbox Code Playgroud)

上面的代码给出了以下编译时错误: -

variable name cannot override a mutable variable

如果name声明为val,那么上面的代码工作正常.

Iul*_*gos 6

简短的回答:您需要传递-Yoverride-vars给 Scala 编译器。

根据规范, avar既是 getter 又是 setter,正常的覆盖规则适用于这些方法。然而,事实证明这会对final关键字和内联产生一些不良后果。编译器中的代码提到需要一些规范说明:

// TODO: this is not covered by the spec. We need to resolve this either by changing the spec or removing the test here.
if (!settings.overrideVars)
  overrideError("cannot override a mutable variable")
Run Code Online (Sandbox Code Playgroud)

相关票证:SI-3770


som*_*ytt 5

如果您可以使用 var 覆盖 var,则覆盖成员可以具有更窄的类型。(这就是覆盖的定义方式。)

然后您可以分配一个更宽类型的值,然后读取它期望更窄的类型,并失败。

所涉及的二传手的插图:

scala> class A ; class B extends A
defined class A
defined class B

scala> abstract class C { var x: A } ; class D extends C { var x: B = _ }
<console>:13: error: class D needs to be abstract, since variable x in class C of type A is not defined
(Note that an abstract var requires a setter in addition to the getter)
       abstract class C { var x: A } ; class D extends C { var x: B = _ }
                                             ^

scala> abstract class C { var x: A }
defined class C

scala> class D extends C { var x: B = _ ; def x_=(a: A) = ??? }
defined class D
Run Code Online (Sandbox Code Playgroud)