Let's say there are following types:
public interface Base {
default void sayHi(){
System.out.println("hi from base");
}
}
public interface Foo extends Base {
@Override
default void sayHi(){
System.out.println("hi from foo");
}
}
public interface Bar extends Base {
}
public class MyClass implements Foo, Bar {
public static void main(String[] args) {
MyClass c = new MyClass();
c.sayHi();
}
}
In this scenario, if main
is executed, "hi from foo" is printed. Why does Foo
's implementation take precedence? Doesn't Bar
inherit sayHi()
from Base
, since if MyClass
was to only implement Bar
, the Base
implementation would be called? So it would make sense for the code to still not compile. Also, since Bar
should have Base
's implementation of sayHi()
, why can't I override it in MyClass
like:
@Override
public void sayHi() {
Bar.super.sayHi();
}
The following error occurs when trying to do so:
bad type qualifier Bar in default super call method, sayHi() is overridden in Foo
This behavior is specified using almost your exact example in JLS 9.4.1, just with some names changed around:
The JLS doesn't seem to give any especially concrete reason that I can see; this is just how the Java designers decided inheritance would work.
This is by design. From JLS 15.12.3: