我正在尝试学习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 */
}
???为什么早期定义语法真的有必要?
答案 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{
}
然后一切正常。