不相关的scala类中的可变可见性

时间:2017-05-13 01:20:50

标签: scala override traits

问题是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"))
}

1 个答案:

答案 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的超级之前。