Scala:使用硬编码值的特征初始化代码
以下代码:Scala:使用硬编码值的特征初始化代码,scala,oop,inheritance,overriding,traits,Scala,Oop,Inheritance,Overriding,Traits,以下代码: trait A{ val s: String = "A" println(s"A's initialiser run, s= $s") } object O1 extends A { override val s = "O1" println(s"Object's initialiser run, s= $s") def foo: Unit = println("I am just being called to instantiate the object!
trait A{
val s: String = "A"
println(s"A's initialiser run, s= $s")
}
object O1 extends A {
override val s = "O1"
println(s"Object's initialiser run, s= $s")
def foo: Unit = println("I am just being called to instantiate the object! :| ")
}
object O2 extends AnyRef with A {
override val s = "O2"
println(s"Object's initialiser run, s= $s")
def foo: Unit = println("I am just being called to instantiate the object! :| ")
}
println("////with inheritance:")
O1.foo
println("////with mix-in:")
O2.foo
印刷品:
////with inheritance:
A's initialiser run, s= null
Object's initialiser run, s= O1
I am just being called to instantiate the object! :|
////with mix-in:
A's initialiser run, s= null
Object's initialiser run, s= O2
I am just being called to instantiate the object! :|
我觉得这种行为很奇怪。我预计会出现以下行为之一:
,“…s=O1”
“…s=O1”
,“…s=A”
“…s=O1”
s
被保留为抽象val
,而不是def
,我可以理解类似的行为,但我发现忽略该值很奇怪。我的问题是:
- 表面下发生了什么导致了这种行为
- 编译器对在带有硬编码值的trait与带有抽象值的trait中运行初始化块的情况有多相似/不同
- 为什么Scala决定这样做,而不是上面详述的两个预期场景
- 编译器不应该警告我们在traits的主体中除了值设置之外还有什么吗
- 这是由
s
is重写子类引起的,Scala编译器将其转换为抽象val,如:
public abstract java.lang.String s();
s
将在所有superclass
完成初始化(A
)后初始化,superclass
完成初始化后,它只会初始化一次(在O1
或O2
),因此,当A
的初始化块尝试打印s
时,将得到null
还有一个参考资料很有帮助: