为什么 super 的这种用法会产生这个结果

时间:2021-01-18 14:14:17

标签: scala

我有以下代码片段:

trait A {
  def print = {
    println("A")
  }
}

trait B {
  def print = {
    println("B")
  }
}

trait C extends A with B {
  override def print = {
    println("C");
    super.print
  }
}

trait D extends B with A {
  override def print = {
    println("D");
    super.print
  }
}

class E extends D with C {
  override def print = {
    println("E");
    super.print
  }
}

打印:

  • E
  • C
  • D
  • A

我理解的方式是:E 首先继承自 D 并覆盖其 printC 然后优先于 D,因为它稍后应用,并且 super 中的 C 调用以某种方式指向 D

在那之后我完全迷失了。我不知道为什么调用 A 而不是 B

特征继承和覆盖的处理方式是否与类不同?

1 个答案:

答案 0 :(得分:5)

从这个声明开始:

class E extends D with C

这读作

class E extends (D with C)

那么 DC 在类层次结构中的顺序是什么?

trait C 应用于 D,因此它可以修改 D 的行为。因此它必须继承 D,所以它被读作

class E extends C extends D

同样的

class C extends B extends A
class D extends A extends B

因此

class E extends C extends B extends A extends D extends A extends B

但是一个类在继承链中只能出现一次,并且是最高(最少派生)的版本被保留下来。所以这变成了

class E extends C extends D extends A extends B

此层次结构与您在 print 实例上调用 E 时看到的输出相匹配。