從Odersky的書編寫一個簡單的例子,導致以下問題:Scala的繼承問題:VAL與DEF
// AbstractElement.scala
abstract class AbstractElement {
val contents: Array[String]
val height: Int = contents.length // line 3
}
class UnifiedElement(ch: Char, _width: Int, _height: Int) extends AbstractElement { // line 6
val contents = Array.fill(_height)(ch.toString() * _width)
}
object AbstractElement {
def create(ch: Char): AbstractElement = {
new UnifiedElement(ch, 1, 1) // line 12
}
}
,
// ElementApp.scala
import AbstractElement.create
object ElementApp {
def main(args: Array[String]): Unit = {
val e1 = create(' ') // line 6
println(e1.height)
}
}
編譯器會引發以下跟蹤:
Exception in thread "main" java.lang.NullPointerException
at AbstractElement.<init>(AbstractElement.scala:3)
at UnifiedElement.<init>(AbstractElement.scala:6)
at AbstractElement$.create(AbstractElement.scala:12)
at ElementApp$.main(ElementApp.scala:6)
at ElementApp.main(ElementApp.scala)
所以編譯器認爲內容仍然是空的,但我在UnifiedContainer中定義了它!
當我用def和evrth替換val完美時,事情變得更加奇怪!
您能否請您認真考慮這種行爲?
你能否澄清'總是使用抽象'def's和'懶惰val's?編譯器不允許你在抽象類中放置'lazy val'。 – jbx 2013-11-17 01:03:59
@jbx,是的,你是對的。那隻適用於特質。 – missingfaktor 2013-11-17 05:22:14
我看到的一些例子在抽象類中使用'val',然後在擴展它的具體類中使用'lazy val'。這是正確的方法嗎? (我仍然在學Scala,所以感到困惑一點) – jbx 2013-11-17 18:54:50