我的问题是关于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()”。任何人都可以解释我的错误在哪里以及实现这两个类的正确方法是什么?
答案 0 :(得分:4)
您在name
类中使用的Human
变量解析为Human
的构造函数参数,Scala将自动为构造函数外部使用的构造函数参数创建私有值。在你的情况下这是不幸的。你可以阻止这个,例如通过不同地命名Human
中的参数,例如nm
:
class Human(nm: String) extends Creature(nm)
答案 1 :(得分:3)
尝试更改此行:
class Human(foo: String) extends Creature(foo) {
所以你不要隐藏name
。
答案 2 :(得分:2)
如果Creature
仅用于子类化,我建议您同时创建类和name
参数摘要,根据我的回答:
Idiomatic Scala way to deal with base vs derived class field names?
这种技术的一个优点是,对特定的,具体的子类使用案例类变得容易得多