为什么方法需要“抽象覆盖”修饰符

时间:2019-04-12 07:43:16

标签: scala

trait Base {
  def someMethod: Unit
}

trait SomeTrait extends Base {
  abstract override def someMethod: Unit = ???
}

class SomeTraitImp extends SomeTrait with Base {
  override def someMethod: Unit = ???
}

错误消息状态:

  

错误:类型=> Unit的特征SomeTrait中的覆盖方法someMethod;    方法someMethod需要使用“抽象覆盖”修饰符         覆盖def someMethod:单位= ???

为什么Scala编译器会限制我重写此方法而不将其标记为抽象?

修改:

我检查了this的答案,它解释了为什么当我们引用可能尚未实现的abstract时方法上需要super关键字。

就我而言,我只是尝试通过全新的实现覆盖someMethod中的SomeTrait,而不是尝试调用super.someMethod

此覆盖是否可以在运行时破坏某些内容?

1 个答案:

答案 0 :(得分:5)

如果您有abstract override,则它必须重写一个具体的实现,以使整个事情变得具体。

这有效:

trait Foo extends Base { def someMethod: Unit = ??? }
class SomeTraitImp extends Foo with SomeTrait 

因为SomeTrait.someMethod覆盖了Foo中的具体实现。 这不是:

class SomeTraitImp extends SomeTrait with Foo

因为Foo中的一种具体方法试图覆盖abstract override中的SomeTraitImpl

您的示例与上一个代码段基本相同,除了您的替代位于类本身而非Foo中。

回答最后一个问题,是的,如果允许的话,它将在运行时中断。考虑一下:

 trait Foo { def foo: String }
 trait Bar extends Foo { abstract override def foo = super.foo + "bar" }
 class Baz extends Foo with Bar { override def foo = super.foo + "baz" }

 println(new Baz().foo)

如果对此进行编译,它将在运行时引发异常,因为super.foo中的Baz调用Bar的{​​{1}},后者调用foo,指的是super.foo,它是抽象的。