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()
}
}
正如我们所知,后斯卡拉编译,斯卡拉将被转移到Java字节码,它是兼容JVM。
以及类Vehicle
变量val speed
,编译后是可见的为它的子类Bike
(在protected
变量),我们可以查看Vehicle
的bytecode
:
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
它在构造方法中设置100
为speed
。
所以init
的Bike
对象时,该speed
字段的值已经在superclass
Vehicle
更新100
。所以super.val
在那里没有意义。
还有另外一个需要东西叫出来:当你直接在你的子类Bike
使用super.speed
,编译器会抛出:
super may not be used on value speed
所以抛出此编译器错误也是造成上述原因。
答案类似的问题在这里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
“正如我们所知,在Scala编译之后,它将转移到Java字节码以与JVM兼容。”这句话没有意义。你使用谷歌翻译? – pedrofurla
@pedrofurla,;) – chengpohi