Проблема с передачей параметров через набор конструкторов - PullRequest
4 голосов
/ 06 июля 2011

Мой вопрос о деталях наследования скалы.У меня есть следующий код.

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)
}

, который производит следующий вывод

Creature was renamed to: Second
I'm human: First

Я ожидаю, что это будет "Я человек: Второй", потому что метод переименования должен изменить значение поля,Я открыл класс Human с помощью декомпилятора:

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);
  }
} 

и вижу "private final String name;"там.Я думаю, что это скрывает поле имени Существа.И

Predef..MODULE$.println(new StringBuilder().append("I'm Human: ").append(this.name).toString());

этот материал выглядит также подозрительно из-за "this.name" вместо вызова метода "this.name ()".Кто-нибудь может объяснить, где моя ошибка и как правильно реализовать эти два класса?

Ответы [ 3 ]

4 голосов
/ 06 июля 2011

Переменная name, которую вы используете в классе Human, преобразуется в параметр конструктора Human, и Scala автоматически создает частные значения для параметров конструктора, которые вы используете вне конструктора.Это неудачно в вашем случае.Вы можете предотвратить это, например, назвав ваш параметр в Human по-другому, например, nm:

class Human(nm: String) extends Creature(nm)
3 голосов
/ 06 июля 2011

попробуйте изменить эту строку:

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

чтобы ты не прятался name.

2 голосов
/ 06 июля 2011

Если Creature предназначен только для подклассов, я бы посоветовал вам сделать класс и параметр name абстрактными согласно моему ответу здесь:

Идиоматический способ Scala дляиметь дело с именами полей базовых и производных классов?

Одним из преимуществ такого метода является то, что тогда становится гораздо проще использовать классы падежей для конкретных, конкретных подклассов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...