【问题标题】:Scala : Why can't we do super.val?Scala:为什么我们不能做 super.val?
【发布时间】:2026-02-20 10:20:04
【问题描述】:

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

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 overriding instance member


    【解决方案1】:

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

    而对于Vehicle类变量val speed,编译后对它的子类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构造方法中找到init动作:

      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

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

    还有一点需要说明:当你在子类Bike中直接使用super.speed时,编译器会抛出:

    super may not be used on value speed
    

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

    【讨论】:

    • "我们知道,Scala编译后会转成Java字节码与JVM兼容。"这句话毫无意义。你用谷歌翻译吗?
    • @pedrofurla, ;)
    【解决方案2】:

    在此处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

    【讨论】: