На вопрос о разнице между new { type T = Int ; val init = 10 }
с AbsCell2 и new AbsCell2 { type T = Int ; val init = 10 }
。
Первый - это так называемые ранние инициализаторы или предварительно инициализированные поля (упомянутые в главе Абстрактные члены в Программирование в Scala). Он позволяет подклассу инициализировать поля перед вызовом суперкласса.
В этом случае init уже был установлен равным 10 до инициализации AbsCell2。
Последний является нормальным наследованием, он создает анонимный класс, затем расширяет AbsCell2, как:
class AbsCell' extends AbsCell {
type T = Int
val init = 10
}
Однако анонимный класс инициализируется после абстрактного класса AbsCell2, поэтому init не доступны при самой инициализации, а именно init является значением по умолчанию Type, в данном случае 0. Таким образом, вы получите 0 в печати。
используйте scalac -Xprint:all Test.scala
, вы увидите следующее:
abstract class AbsCell2 extends Object {
<stable> <accessor> def init(): Object;
....
def <init>(): AbsCell2 = {
AbsCell2.super.<init>();
AbsCell2.this.value = {
scala.this.Predef.println("Hello ".+(AbsCell2.this.init()));
AbsCell2.this.init()
};
()
}
};
// normal initialization
final class anon$1 extends AbsCell2 {
private[this] val init: Int = _;
<stable> <accessor> def init(): Int = anon$1.this.init;
....
def <init>(): <$anon: AbsCell2> = {
anon$1.super.<init>();
anon$1.this.init = 10;
()
}
};
// early initialization
final class anon$2 extends AbsCell2 {
private[this] val init: Int = _;
<stable> <accessor> def init(): Int = anon$2.this.init;
....
def <init>(): <$anon: AbsCell2> = {
val init: Int = 10;
anon$2.this.init = init;
anon$2.super.<init>();
()
}
}
Из кода видно, что для нормальной инициализации init устанавливается в 3 после инициализации суперкласса AbsCell2, когда вызывается AbsCell2.this.init (), он фактически ссылается на поле init подкласса и 3 еще предстоит установить, поэтому мы получаем значение типа по умолчанию. Напротив, при ранней инициализации сначала устанавливают значение init 3, а затем вызывают инициализацию суперкласса 6