I am practicing this code from JavaTpoint for learning inheritance in Scala. But I cannot access the member Bike from the class Vehicle who's value is initialized to zero. I tried by super type reference but it still shows the overridden value. Why does it not allow to access the super class field and directs to the overridden sub class field (speed) . here is the code and the output.
Thanking in advance.
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()
}
}
As we know, after Scala compile, Scala will be transfered to Java bytecode, it's for compatible with JVM.
And for the class Vehicle
variable val speed
, after compile it's visible for it's subclass Bike
(the protected
variable), we can view the bytecode
of Vehicle
:
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
As we can see, it's init the speed
's value 10 in the Vehicle
constructor method.
and we also can find the init action in Bike
constructor method:
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
it's setting 100
for speed
in constructor method.
so when init
the Bike
object, the speed
field's value has been updated to 100
in the superclass
Vehicle
. so super.val
will not make sense in there.
and there is another thing need to call out: when you use the super.speed
directly in your subclass Bike
, the compiler will throw:
super may not be used on value speed
so this compiler error thrown is also caused by the above reason.
Answers to similar questions here overriding-vals-in-scala, or here cannot-use-super-when-overriding-values say: Scala compiler does not allow to use super on a val
Why is that? Discussion in last link above points to: SI-899. And the first comment there says following: it was changed so that traits could override vals to be more uniform with classes