有关与AbsCell2和new AbsCell2 { type T = Int ; val init = 10 }
new { type T = Int ; val init = 10 }
之间的差异问题。
第一个是所谓的早期初始化或预先初始化的字段(在Programming Scala中的抽象成员一章中提到过)。它允许子类在超类被调用之前初始化字段 在这种情况下,init有。已经AbsCell2的初始化之前被设定为10
后者是正常的继承,它会创建一个匿名类,然后扩展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>();
()
}
}
从代码中,我们可以看到,对于正常的初始化,初始化时的初始化后设置为3超类AbsCell2,当AbsCell2.this.init()被调用时,它实际上是指子类的init字段,而3还没有设置,所以我们得到默认的类型值。相反,早期初始化首先将init设置为3然后调用超级类初始化。
本示例借用Martin Ordersky提供的演示文稿。 http://lampwww.epfl.ch/~odersky/ –
但是现在在REPL中执行'cell.init',它会_will_向您显示10.您的问题是为什么在对象初始化之前它不打印10? –
我想爱国者也在问为什么'细胞。get'返回0,以及如何让它返回10. –