为什么Scala子类在使用主构造函数继承时会创建字段副本?

时间:2015-12-24 20:22:30

标签: scala inheritance

为什么子类在使用主构造函数继承时会创建字段副本?

例如

object Question
{
  class Animal(var name : String) {

    def setName(name : String) {
      this.name = name
    }
  }

  class Dog(name : String) extends Animal(name) {
    this.setName("dog: " + name)

    override def toString: String = this.name // this actually returns "Billy"
  }

  def main(args: Array[String]) {
    val dog = new Dog("Billy")
    println(dog.toString) // output "Billy", why?
    println(dog.name) // output "dog: Billy", why?
  }
}

正如您所看到的,dog.toString()返回“Billy”而不是“dog:Billy”,这是否意味着this.name与继承的name不同?如果是这样,为什么dog.name会返回“dog:Billy”?

2 个答案:

答案 0 :(得分:4)

如果使用-Xlint选项运行编译器,您应该看到以下内容。

  

警告:类中的私有[this]值名称Dog shadow可变名称   继承自Animal类。对名称的更改将不可见   在班级狗 - 你可能想给他们不同的名字。

如果将name类重命名为Dog类,则警告消失,输出更加一致,可能更接近预期。

答案 1 :(得分:0)

这是您的代码调试结果

your code debug result

所以,你可以看到实际上有两个变量实例" name"。一个来自" Animal",一个来自" Dog"。构造函数在Scala中的工作方式略有不同 - 您所谓的构造函数参数实际上是使用构造函数参数初始化的局部变量。 不幸的是,我无法为此提供任何优雅的解决方案。 而且,我可能错了。如果我是,请纠正我。

更新

Try this question.