【问题标题】:Issue with passing parameters via set of constructors通过一组构造函数传递参数的问题
【发布时间】:2011-09-29 14:53:52
【问题描述】:

我的问题是关于 scala 继承细节。我有以下代码。

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

并查看“私有最终字符串名称;”那里。我认为它隐藏了生物名称字段。和

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

这个东西看起来也很可疑,因为“this.name”而不是方法调用“this.name()”。谁能解释我的错误在哪里以及实现这两个类的正确方法是什么?

【问题讨论】:

    标签: scala


    【解决方案1】:

    您在Human 类中使用的name 变量解析为Human 的构造函数参数,Scala 将自动为您在构造函数之外使用的构造函数参数创建私有变量。这对你来说是不幸的。您可以防止这种情况,例如通过以不同的方式命名 Human 中的参数,例如nm:

    class Human(nm: String) extends Creature(nm)
    

    【讨论】:

    • 看起来很混乱。谢谢,我现在明白了。
    【解决方案2】:

    尝试更改此行:

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

    所以你不要隐藏name

    【讨论】:

      【解决方案3】:

      如果Creature 仅用于子类化,我建议您将类和name 参数都设为抽象,按照我在此处的回答:

      Idiomatic Scala way to deal with base vs derived class field names?

      这种技术的一个优点是,为特定的、具体的子类使用案例类变得容易得多

      【讨论】:

      • 非常感谢,凯文。该线程看起来非常接近我的问题。我可以在不创建新线程的情况下得到答案。
      猜你喜欢
      • 1970-01-01
      • 2021-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多