"override" 组合遗传特征时如何工作?

How does "override" work when inherited traits are combined?

我正在 Scala 中试验多重继承。我知道有一个从右到左的分辨率,但我不明白 override 关键字的作用。让我们考虑以下片段:

trait A           { def          method                }
class B extends A { def          method = println("B") }
trait C extends A { override def method = println("C") }
trait E           {                                    }
class D extends B with C with E

它编译得很好,但是如果我从定义 method 的最右边的特征中删除 override,它就坏了。为什么是这样 ?即使没有关键字,方法也不会被覆盖吗?

如果特征应该替换(而不是提供缺失的实现)方法,则需要使用 override 关键字。无论其他方法是在特征中还是以其他方式提供,都是如此。例如:

trait X { def foo = "foo" }
class Y { def foo = "bar" }
class Z extends Y with X  // Does not compile

所以它与抽象 类 的规则完全相同:您需要重写您替换其实现的方法(而不是第一次提供)。

注意with traits,只要最后提供的方法是override即可:

trait L { def m: String }
trait M extends L { def m = "m" }
trait N extends L { def m = "M" }
trait O extends L { override def m = "?" }
class P extends M with N with O  // All good
class Q extends M with N { override def m = "." } // Also good

这里,算作"already provided"的是前段的延期,好结局就好。所以

class R extends O with N

不起作用,因为 O 提供了 m 的实现(如果需要可以覆盖),但是 N 然后尝试应用另一个,但它不是允许覆盖。

另一方面,P 很好,因为即使 MN 都尝试为 m 提供实现,O最后并声明其实现可能会覆盖。确实如此,一切都很好。