基于上一个问题,以下代码编译正常
trait Logger {
def log(msg: String): Unit
}
trait LoggerA extends Logger {
def log(msg: String) = ???
}
trait LoggerB extends Logger {
override def log(msg: String) = ???
}
class Logged1 extends LoggerA
class Logged2 extends LoggerB
class Logged3 extends LoggerA with LoggerB
Run Code Online (Sandbox Code Playgroud)
在override不要求LoggerA ,因为没有具体的实施log中Logger。
但是,如果我override从中删除LoggerB不再编译:
class Logged3 inherits conflicting members:
def log(msg: String): Nothing (defined in trait LoggerA) and
def log(msg: String): Nothing (defined in trait LoggerB)
(note: this can be resolved by declaring an `override` in class Logged3.)
Run Code Online (Sandbox Code Playgroud)
为什么override在这种特定情况下需要?指定是否会override以某种方式更改方法或类?
\n\n如果 M\xe2\x80\xb2 不是抽象成员,则 M 必须标记为
\noverride.\n... 或者 M 和 M\xe2\x80\xb2 都覆盖在 a 中定义的第三个成员 M\'\' \n包含 M 和 M\' 的类的基类。
同样在第 5.1.3 节“类成员”中,也有与 OP 类似的 override 使用
\ntrait A { def f: Int }\ntrait B extends A { def f: Int = 1 ; def g: Int = 2 ; def h: Int = 3 }\ntrait C extends A { override def f: Int = 4 ; def g: Int }\ntrait D extends B with C { def h: Int }\nRun Code Online (Sandbox Code Playgroud)\n因此至少它看起来确实是一种特定的行为。
\n基于fr_andres 的回答和学习 Scala,第 9 章:对象、案例类和特征
\n\n\n当编译为 .class 二进制文件时,扩展类 A 和特征 B 和 C 的类实际上扩展了一个类,该类扩展了另一个类,该类又扩展了另一个类。
\n
由于线性化意味着有效
\nLoggerA (has concrete log)\n ^\n |\nLoggerB (also has concrete log)\n ^\n |\nLogged3\nRun Code Online (Sandbox Code Playgroud)\n并且override在覆盖具体实现时是必要的。