My question is about scala inheritance details. I have the following code.
package scalasandbox
object Main {
def main(args: Array[String]): Unit = {
val creature: Creature = new Human("First")
creature.rename("Second")
creature.introduce
}
}
class Creature(var name: String) {
def introduce = println("I'm creature: " + name)
def rename(newName: String) = {
println("Creature was renamed to: " + newName)
name = newName
}
}
class Human(name: String) extends Creature(name) {
override def introduce = println("I'm Human: " + name)
}
which produces the following output
Creature was renamed to: Second
I'm human: First
I expect it to be "I'm human: Second" because rename method should change the field value. I have opened Human class with decompiler:
package scalasandbox;
import scala.Predef.;
import scala.ScalaObject;
import scala.collection.mutable.StringBuilder;
import scala.reflect.ScalaSignature;
@ScalaSignature(bytes="\006\001\0212A!\001\002\001\013\t)\001*^7b]*\t1!\001\007tG\006d\027m]1oI\n|\007p\001\001\024\007\0011!\002\005\002\b\0215\t!!\003\002\n\005\tA1I]3biV\024X\r\005\002\f\0355\tABC\001\016\003\025\0318-\0317b\023\tyABA\006TG\006d\027m\0242kK\016$\b\002C\t\001\005\003\005\013\021\002\n\002\t9\fW.\032\t\003'Yq!a\003\013\n\005Ua\021A\002)sK\022,g-\003\002\0301\t11\013\036:j]\036T!!\006\007\t\013i\001A\021A\016\002\rqJg.\033;?)\taR\004\005\002\b\001!)\021#\007a\001%!)q\004\001C!A\005I\021N\034;s_\022,8-Z\013\002CA\0211BI\005\003G1\021A!\0268ji\002")
public class Human extends Creature
implements ScalaObject
{
private final String name;
public void introduce()
{
Predef..MODULE$.println(new StringBuilder().append("I'm Human: ").append(this.name).toString());
}
public Human(String name)
{
super(name);
}
}
and see "private final String name;" there. I think it hides Creature name field. And
Predef..MODULE$.println(new StringBuilder().append("I'm Human: ").append(this.name).toString());
this stuff looks also suspicious because of "this.name" instead of method call "this.name()". Could anyone explain where is my mistake and what is the correct way of implementing those two classes?
The name
variable that you use in the Human
class resolves to the constructor parameter of Human
, and Scala will automatically create private vals for constructor parameters that you use outside the constructor. This is unfortunate in your case. You can prevent this e.g. by naming your parameter in Human
differently, e.g. nm
:
class Human(nm: String) extends Creature(nm)
try by changing this line:
class Human(foo: String) extends Creature(foo) {
so you don't hide name
.
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