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

Scala : Why can't we do super.val?

我正在练习 JavaTpoint 中的这段代码,以学习 Scala 中的继承。但是我无法从值初始化为零的 class Vehicle 访问成员 Bike。我尝试了超类型引用,但它仍然显示被覆盖的值。为什么它不允许访问 super class 字段并指向覆盖的 sub class 字段 (speed) 。这是代码和输出。 提前致谢。

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()
  }
}

我们知道,Scala编译后,Scala会转为Java字节码,是为了兼容JVM

而对于 class Vehicle 变量 val speed,编译后它是可见的,因为它是子class Bikeprotected 变量), 我们可以查看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

正如我们所见,它是在 Vehicle 构造方法中初始化 speed 的值 10

我们也可以在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

它在构造方法中为 speed 设置 100

所以当 init Bike 对象时,speed 字段的值在 superclass Vehicle 中更新为 100。所以 super.val 在那里没有意义。

还有一件事需要指出:当你直接在子classBike中使用super.speed时,编译器会抛出:

super may not be used on value speed

所以抛出的这个编译器错误也是由上述原因造成的

此处类似问题的答案, or here cannot-use-super-when-overriding-values说:Scala compiler does not allow to use super on a val

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