问题是C trait如何使用D类中指定的str字段。 D从A延伸,因此它没有在任何合同中指定的str。即使C能够使用它。当我从D编译器中删除str时将无法编译此代码。怎么知道来自D的str与B中的str无关是同样的事情。我希望这种行为是动态类型语言,而不是静态类型。
trait A {
def receive(): PartialFunction[String, Any]
}
trait B extends A {
def str: String
}
trait C extends B {
abstract override def receive(): PartialFunction[String, Any] =
cReceive.orElse(super.receive())
val cReceive: PartialFunction[String, Any] = {
case "MemberUp" ⇒ s"$str"
}
}
class D extends A {
override def receive(): PartialFunction[String, Any] = {
case _ ⇒
}
def str: String = "My string"
}
class E extends D with C
object Main extends App {
private val e = new E
println(e.receive().apply("MemberUp"))
}
答案 0 :(得分:0)
魔法发生在E。
基本上B说"会有一个方法str返回字符串"。现在,当在C中调用它时,将查看实现。
如果E会定义str,那么一切都会很清楚。在这种情况下,str取自D.当编译器构建E时,它首先定义哪些方法可用,然后按线性化定义的顺序查找实现(参见Linearization order in Scala)。这意味着可以使用实现,就像它在E中定义一样(因为def str是E的一部分。
注意:如果您已经更改了D中的接收以返回其他内容,那么仍然会返回str。这是因为从线性化顺序C实现出现在D和D成为C的超级之前。