Suppose I have the following abstract class:
abstract class A (var is_happy : Boolean) {
def toggle_happiness();
}
And now I want to define a
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.
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.