【发布时间】:2018-02-23 15:39:52
【问题描述】:
以下代码:
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 时,我可以理解类似的行为,但我觉得很奇怪这个值被简单地忽略了。我的问题是:
- 导致这种行为的表面原因是什么?
- 编译器看到在具有硬编码值的特征与具有抽象值的特征中运行初始化块的情况有多么相似/不同。
- 为什么 Scala 决定这样做,而不是上面详述的两个预期场景。
- 编译器不应该警告我们在特征体中除了值设置以外的任何内容?
【问题讨论】:
标签: scala oop inheritance overriding traits