为什么抽象方法有时需要重写?

2024-03-05

基于一个上一个问题 https://stackoverflow.com/questions/66182368/stack-modification-traits-in-scala-not-working,下面的代码编译OK

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

The override不需要在LoggerA因为没有具体的实施log in Logger.

但是如果我删除override from 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.)

Why is override在此需要具体案例 https://scastie.scala-lang.org/IAD8lf5yST6q3s0QTrEWQA?是否指定override以某种方式改变方法或类?


我猜它是由SLS 5.1.4 覆盖 https://scala-lang.org/files/archive/spec/2.13/05-classes-and-objects.html#overriding

如果 M′ 不是抽象成员,则 M 必须被标记override。 ...或者 M 和 M' 都覆盖在 a 中定义的第三个成员 M'' 包含 M 和 M' 的类的基类。

也在部分5.1.3 类成员 https://scala-lang.org/files/archive/spec/2.13/05-classes-and-objects.html#class-members与 OP 有类似的 override 使用

trait A { def f: Int }
trait B extends A { def f: Int = 1 ; def g: Int = 2 ; def h: Int = 3 }
trait C extends A { override def f: Int = 4 ; def g: Int }
trait D extends B with C { def h: Int }

因此至少它看起来确实是一种特定的行为。

基于fr_andres 的回答 https://stackoverflow.com/a/39958910/5205022 and 学习 Scala,第 9 章。对象、案例类和特征 https://www.oreilly.com/library/view/learning-scala/9781449368814/ch09.html#traits_section

扩展类 A 和特征 B 和 C 的类实际上是扩展类 A 类,它扩展另一个类,它扩展另一个类,当 编译为.class 二进制文件。

由于线性化意味着有效

LoggerA (has concrete log)
  ^
  |
LoggerB (also has concrete log)
  ^
  |
Logged3

and override当覆盖具体实现时是必要的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么抽象方法有时需要重写? 的相关文章

随机推荐