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 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
正如我们所见,它是在 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
我正在练习 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 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
正如我们所见,它是在 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
所以抛出的这个编译器错误也是由上述原因造成的
此处类似问题的答案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