サブクラスは親クラス、親クラスのメソッドやフィールドを上書きし、これらのフィールドやメソッドの初期化に依存している場合は、この時間は、次のような問題があるでしょう
class Creature {
val range: Int = 10
val env: Array[Int] = new Array[Int](range)
//lazy val env: Array[Int] = new Array[Int](range)
}
class Ant extends Creature {
//override val range = 2
override val range = 2
}
-------------------------------------------------------------
val ant = new Ant
println(ant.range)
println(ant.env.length)
このとき、設定の順序
(1)独自のコンストラクタを呼び出す前にAntのコンストラクタ、コンストラクタのクリーチャーを呼び出します
(2)クリーチャー構成は、それがフィールドが10に設定されている範囲で
アレイを初期化するため(3)クリーチャーENVコンストラクタは、コールの範囲()の値であります
アリの(4)の範囲をフィールドの値の範囲出力に書き換えられる(まだ初期化されていない)クラス
(5)範囲メソッドは(オブジェクトが割り当てられているときに空間を成形するすべてのフィールドの初期値である)、0を返します
(6)長さのENV配列はゼロに設定されます。
(7)Antのコンストラクタは、その範囲フィールドが2に設定され、継続します。
だから、ENVの大きさは、数ありますか?0は、ない事故を意味し、何の驚きの驚きではありませんか?
問題解決、プログラムの4種類
(1)サブクラスは、スーパークラスをオーバーライドしません
サブクラスを書き換えることができないので、(2)valが、最終的に宣言することができます。
(3)valが怠惰なスーパークラスで宣言されたが、とても安全で効率的ではありません。
(4)構文はまた、スーパークラスのコンストラクタは、初期化サブクラスフィールドvalを行う前であることが事前に使用されてもよい定義します
表示するには、subversionの3つの方法が、ハハ、事前に定義された~~
多重継承のように見えたが、それは多重継承ではありません
class Ant2 extends {
override val range = 3
} with Creature
ます。https://www.jianshu.com/p/d66ae2359968で再現