Why can't concrete members be overridden with

2019-07-11 14:58发布

问题:

For instance, in the following code:

class Animal
class Dog extends Animal
trait Base {
  def a: Animal = new Dog
}
trait Deri extends Base {
  override val a: Dog
}

The following error is given:

error: overriding value a in trait Deri of type Dog; method a in trait Base of type => Animal needs to be a stable, immutable value; (Note that value a in trait Deri of type Dog is abstract, and is therefore overridden by concrete method a in trait Base of type => Animal)

I want to know, since I have explicitly modified a in Deri with override, while does Scala choose to do the other way around(overriding a in Deri with that in Base as indicated in error msg)?

回答1:

According to Scala Spec, a concrete definition always overrides an abstract definition.

This definition also determines the overriding relationships between matching members of a class C and its parents. First, a concrete definition always overrides an abstract definition. Second, for definitions M and M' which are both concrete or both abstract, M overrides M′ if M appears in a class that precedes (in the linearization of C) the class in which M′ is defined.

So, to make it compiled, you have to make sure the abstract method is overridable by the concrete one. Change Deri:

trait Deri extends Base { override def a:Animal }

or change Base

trait Base { val a: Dog = new Dog }