Scala - 构造顺序和早期定义语法

时间:2013-06-03 11:51:09

标签: scala inheritance syntax

我正在尝试学习Scala,并认为我会先阅读“Scala for the Impatient”。他在那里通过使用以下类引用了施工顺序的问题:

class Animal {
  val range: Int = 10
  val env: Array[Int] = new Array[Int](range)

}

class Ant extends Animal {
  override val range: Int = 2
}

然后他解释了为什么env最终成为一个空数组[Int]并继续解释防止它的方法,包括早期定义语法。

但是......我不能通过这样做来阻止它:

class Animal(val range: Int = 10) {
  val env: Array[Int] = new Array[Int](range)
  /* do animal stuff */
}

class Ant(override val range: Int = 2) extends Animal(range) {
     /* do ant stuff */
}

???为什么早期定义语法真的有必要?

1 个答案:

答案 0 :(得分:4)

我认为更好的方式来看待早期实例化的需要来自于混合特征。对于traits,你将没有可以调整以解决此类问题的构造函数。考虑一下这个非常微不足道且完全不​​切实际的例子:

trait Foo{
  val bar:String
  val barLength = bar.length()
}

object MyFoo extends Foo{
  val bar = "test"
}

就目前而言,当创建MyFoo时,此代码将抛出NullPointerException,因为在调用bar时尚未定义bar.length()。但是如果您使用了早期初始化,并将MyFoo重新定义为:

object MyFoo extends {val bar = "test"} with Foo{

}

然后一切正常。