代码在这里:
abstract class Element {
def contents: Array[String]
val height = contents.length
val width = if(height ==0 ) 0 else contents(0).length
override def toString = contents(0)
}
class ArrayElement(override val contents: Array[String]) extends Element
class LineElementT(s: String) extends Element {
override def contents = Array(s)
}
class LineElementF(s: String) extends Element {
override val contents = Array(s)
}
除LineElementF
之外,这三个子类都可以,NullPointerException
在使用val lef = new LineElementF("Wrong")
创建实例时会抛出padding
答案 0 :(得分:4)
此NPE发生在高度初始化时。在高度初始化时,LineElementF的val内容未初始化。
你可以通过将高度和宽度都声明为懒惰来避免这种NPE:
lazy val height = contents.length
lazy val width = if(height ==0 ) 0 else contents(0).length
答案 1 :(得分:1)
Scala语言也有一个特殊的语法(有时称为early definitions or early initilizer),它允许在其超类的构造函数之前执行子类的构造函数:
class LineElementEI(s: String) extends {
override val contents = Array(s)
} with Element
澄清为什么常规的“延迟初始化”不适用于LineElementF
:在超类的主体中,您试图评估contents.length
,但子类的主体仅被评估 超类之后,contents
仍为null
。您可以使用所有依赖于子类初始化的字段进行延迟求值来解决它,也可以更改初始化顺序,如上所示。