class Abs(var name: String){
}
class AbsImpl(override var name: String) extends Abs(name){
}
上面的代码给出了以下编译时错误: -
variable name cannot override a mutable variable
If name is declared val, then above code works fine.
5 回答
4
如果您可以使用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
1
简短的回答:您需要将 -Yoverride-vars 传递给Scala编译器 .
根据规范, var 既是getter又是setter,正常的覆盖规则适用于这些方法 . 然而,这被证明会产生一些不良后果w.r.t.到 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")
5 回答
如果您可以使用var覆盖var,则覆盖成员可以具有更窄的类型 . (这就是如何定义覆盖 . )
然后,您可以分配更宽类型的值,然后读取它,期望更窄的类型,然后失败 .
涉及的二传手的插图:
简短的回答:您需要将
-Yoverride-vars
传递给Scala编译器 .根据规范,
var
既是getter又是setter,正常的覆盖规则适用于这些方法 . 然而,这被证明会产生一些不良后果w.r.t.到final
关键字和内联 . 编译器中的代码提到需要一些规范说明:相关票证:SI-3770
我相信意图只是设置继承的
var name
的值 . 这可以通过这种方式实现(没有override var
):这种歧义来自于
AbsImpl
中的本地varname: String
,它是从Abs
继承的var name: String
命名的 . 一个类似的代码,在语法上不那么模糊,但也不那么优雅:当你想覆盖var等同于尝试覆盖java中不可能的字段时 .
当您尝试覆盖的
var
已经具有分配时,会发生这种情况 . 我不确定为什么这是被禁止的,但也没什么意义 .另见this question .
将
name
定义为抽象要么