我在我的scala代碼中發現了一個錯誤,令我感到困惑。以下是該問題的簡化版本。當子類使用val實現它時,Scala抽象方法在超類中爲null?
在抽象類的構造函數中,我想檢查一些關於抽象方法的斷言。 因此,當創建子類的對象時,將檢查這些斷言,以查看是否所有實現都應該如此。
它出錯時,子類實現使用 「VAL」 但是抽象方法:
Scala代碼:
abstract class A {
def aval : String
assert(aval != null, "aval == null")
assert(aval == "B", "aval: "+aval)
}
class B extends A {
def aval = "B"
}
class C extends A {
val aval = "B"
}
object VariousScalaTests {
def main(args : Array[String]) : Unit = {
val b = new B
val c = new C
}
}
斯卡拉錯誤:
Exception in thread "main" java.lang.AssertionError: assertion failed: aval == null
at scala.Predef$.assert(Predef.scala:92)
at A.<init>(VariousScalaTests.scala:4)
at C.<init>(VariousScalaTests.scala:12)
at VariousScalaTests$.main(VariousScalaTests.scala:19)
at VariousScalaTests.main(VariousScalaTests.scala)
所以未能在最後一行代碼:「val c = new C」。 B類作品完美,但C類不是!唯一的區別是C使用「val」實現aval並使用「def」實現B.
所以我的問題,最重要的是,爲什麼這種差異?我不明白髮生了什麼事。
有沒有辦法讓它在scala中的兩種情況下都能工作?還是我錯過了一個更優雅的方式來聲明我想要的scala?
Java代碼很好地解釋!我現在看到... 考慮到這樣的行爲,「避免從構造函數調用虛擬方法」似乎是很好的建議。當然在scala中,就像在java代碼中一樣,它更清楚發生了什麼。 我會以另一種方式來優雅地檢查我的具體情況下的子類,您的鏈接可能會有所幫助。 至少這個錯誤的奧祕現在已經消失了;-) – 2010-07-28 14:01:48