Suppose I have the following abstract class:
abstract class A (var is_happy : Boolean) {
def toggle_happiness();
}
And now I want to define a concrete class which implements the toggle_happiness()
method:
class B (is_happy : Boolean) extends A (is_happy) {
def toggle_happiness() = {
is_happy = !is_happy
}
}
Scala's compiler gives me:
error: reassignment to val
is_happy = !is_happy
^
What's going on here? I thought that is_happy
referred to a var
in my class that is set by my constructor. Do I have a conflict with the name is_happy
?
Thanks, Dan
See this question. Essentially, Scala thinks that you're trying to assign to the constructor parameter, is_happy
, rather than the var
, is_happy
, which just happens to have the same name. Some solutions are to:
var
abstract in the base class._is_happy
). Since parameter names are part of the public API of your constructors/methods, this may not be advisable.You're fortunate that the problem was detected at compile time in your case. This issue can lead to very surprising runtime behavior when it goes undetected.
There is another simple solution. One that only requires to modify B
(no need to change the base class) and won't modify the interface (no parameter renaming).
Just introduce a private method that returns this, and explicitly dereference this:
class B (var is_happy : Boolean) extends A {
private def self = this
def toggle_happiness() = {
self.is_happy = !self.is_happy
}
}
Note that this work around is localized to B
. Everywhere else (included in derived classes) you can keep using just is_happy
(no need for self.is_happy
).
As a side note, we should really be able to directly dereference this
, as in this.is_happy
(instead of adding the self
method and doing self.is_happy
). But for some reason the compiler will blindly treat this.is_happy
the same as is_happy
, so we get back to square one and this.is_happy
actually still point to B
's parameter rather than A
's variable. This very much looks like a compiler bug to me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With