Lifu Huang Lifu Huang - 1 month ago 5
Scala Question

Why can't concrete members be overridden with abstract ones in scala?

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)?

Answer

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 }