Reputation: 795
I find a strange result in the following code.
object Practice {
class A(val seq: Seq[Int]){
println(f, seq)
def f: Seq[Int] = seq
}
class B(override val seq: collection.mutable.WrappedArray[Int]) extends A(null)
def main(args: Array[String]): Unit = {
new B(Array(3,4,2))
}
}
The print result is "(WrappedArray(3, 4, 2),null)", which means seq
and f
are different! Why?
Upvotes: 1
Views: 607
Reputation: 40500
The "body" of the scala class is actually the body of the constructor in java.
Something like public A(seq: Seq) { this.seq = seq; prinltn(f(), seq); }
This is executed during B's construction, when it calls A(null)
, and prints the value of the parameter, which is null
. The parameter shadows the member.
Try changing the definition of A
to something like this:
class A(_seq: Seq[Int]){
println(f, seq)
val seq: Seq[Int] = _seq
def f: Seq[Int] = seq
}
Now, new B(...)
will print two identical values.
The take away from this is - don't override vals. It is almost never necessary, and, as you can see, may be trickier than it looks.
If val
is a super-class parameter, you can always just pass the correct value in when constructing the subclass rather than overriding. If it is not a parameter, just make it a def
in the superclass.
Upvotes: 3