7

Note: This is a question born out of pure curiosity. I played around for fun and I encountered a curious behavior that I couldn't fully explain. I am not trying to solve any actual problem, nor am I a proponent of multiple inheritance. ;-)

As far as I know, in Java, when a class inherits multiple default methods with the same signature and return type from different interfaces, that class normally has to override that method and provide its own implementation to resolve the ambiguity (the overriding method may explicitly call one of the default methods using InterfaceName.super.foo()). See here for example.

This is not true, however, if these interfaces only provide the same default method because they all extend the same super-interface, and all interfaces only inherit that default method from that super-interface. This is fine for the compiler. Ambiguity would only be introduced if some of these interfaces were to override that default method with their own implementation (and in that case, the compiler would complain).

However, if only one of the interfaces overrides the default method, the compiler curiously doesn't complain.

For example, the following compiles and runs fine:

interface Creature {
    default void whoAmI() {
        System.out.println("creature");
    }
}

interface Horse extends Creature {
}

interface Human extends Creature {
    @Override
    default void whoAmI() {
        System.out.println("human");
    }
}

public class Centaur implements Horse, Human {
    public static void main(String... args) {
        new Centaur().whoAmI(); // prints 'human'
    }
}

Interestingly, the output is human, rather than creature. (Well, the other way around would have been equally interesting.) My guess would have been that the compiler wouldn't allow this, because the method call is ambiguous.

Q: Is this intended behavior? If yes, what is the rationale? (I guess one could argue that if only one interface overrides the default method, then that override should be given priority). Or is it just that the compiler somehow doesn't detect this "hidden" ambiguity and exhibits some undefined behavior by linking the method call to the overriding method declaration in interface Human? Any canonical references would be a plus. :)

Malte Skoruppa
  • 1,232
  • 1
  • 19
  • 25

0 Answers0