Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue with passing parameters via set of constructors

Tags:

scala

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?

like image 795
Soteric Avatar asked Jan 20 '23 07:01

Soteric


2 Answers

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)
like image 70
Jean-Philippe Pellet Avatar answered Jan 28 '23 23:01

Jean-Philippe Pellet


try by changing this line:

class Human(foo: String) extends Creature(foo) {

so you don't hide name.

like image 26
shellholic Avatar answered Jan 28 '23 23:01

shellholic