4
votes
trait Base {
  def someMethod: Unit
}

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

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

Error message states:

Error: overriding method someMethod in trait SomeTrait of type => Unit; method someMethod needs `abstract override' modifiers override def someMethod: Unit = ???

Why Scala compiler restricts me from overriding this method without marking it as an abstract?

Edit:

I checked this answer and it explains why abstract keyword required on method when we reference to super which may not have implementation yet.

In my case I'm just trying to override someMethod in SomeTrait by brand new implementation and not trying to call super.someMethod.

Is this override can break something at runtime?

1
Can you let us know which Scala version you are using, and give some real code that shows this error?Tim
@Tim scala 2.12.7. this is the real code that shows the error.Bogdan Vakulenko

1 Answers

6
votes

If you have abstract override, it must override a concrete implementation for the whole thing to become concrete.

This works:

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

Because SomeTrait.someMethod overrides a concrete implementation in Foo. This does not:

class SomeTraitImp extends SomeTrait with Foo

Because a concrete method in Foo is trying to override an abstract override in SomeTraitImpl.

Your example is essentially the same as last snippet, except your override is in the class itself rather than in Foo.

And to answer your last question, yes, this would break at runtime if it was allowed. Consider this:

 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)

If this compiled, it would trow an exception at runtime, because super.foo in Baz calls Bar's foo, which calls super.foo, which refers to Foo.foo, which is abstract.