Scala:为什么我们不能做super.val?

问题描述:

我正在从JavaTpoint中练习这段代码,以学习Scala中的继承。但是我无法从班级车辆中获得成员自行车,其价值已初始化为零。我尝试了超类型参考,但它仍然显示重写的值。为什么它不允许访问超类字段并指向重写的子类字段(速度)。这里是代码和输出。 预先感谢。Scala:为什么我们不能做super.val?

class Vehicle { 
    val speed = 0 
    println("In vehicle constructor " +speed) 
    def run() { 
    println(s"vehicle is running at $speed") 
    } 
} 

class Bike extends Vehicle { 
    override val speed = 100 
    override def run() { 
    super.run() 
    println(s"Bike is running at $speed km/hr") 
    } 
} 

object MainObject3 { 
    def main(args:Array[String]) { 
    var b = new Bike() 
    b.run() 
    var v = new Vehicle() 
    v.run() 
    var ve:Vehicle=new Bike() 
    println("SuperType reference" + ve.speed) 
    ve.run() 
    } 
} 

How do I get the result using instance of Bike.

正如我们所知,后斯卡拉编译,斯卡拉将被转移到Java字节码,它是兼容JVM

以及类Vehicle变量val speed,编译后是可见的为它的子类Bike(在protected变量),我们可以查看Vehiclebytecode

public Vehicle(); 
    Code: 
     0: aload_0 
     1: invokespecial #63     // Method java/lang/Object."<init>":()V 
     4: aload_0 
     5: bipush  10 
     7: putfield  #13     // Field speed:I 
     10: return 

我们可以看到,它的init的speed的值中的Vehicle构造方法。

,我们还可以找到Bike构造函数初始化动作:

public Bike(); 
    Code: 
     0: aload_0 
     1: invokespecial #67     // Method Vehicle."<init>":()V 
     4: aload_0 
     5: bipush  100 
     7: putfield  #13     // Field speed:I 
     10: return 

它在构造方法中设置100speed

所以initBike对象时,该speed字段的值已经在superclassVehicle更新100。所以super.val在那里没有意义。

还有另外一个需要东西叫出来:当你直接在你的子类Bike使用super.speed,编译器会抛出:

super may not be used on value speed 

所以抛出此编译器错误也是造成上述原因。

+0

“正如我们所知,在Scala编译之后,它将转移到Java字节码以与JVM兼容。”这句话没有意义。你使用谷歌翻译? – pedrofurla

+0

@pedrofurla,;) – chengpohi

答案类似的问题在这里overriding-vals-in-scala,或在这里cannot-use-super-when-overriding-values说:Scala compiler does not allow to use super on a val

这是为什么?在上面的链接中讨论指向:SI-899。第一条评论如下:it was changed so that traits could override vals to be more uniform with classes