Why Java 8 compilation fails when Default Method is overridden by subclass's Static Method?

Cristiano Passos :

Given Java 8, why the code bellow fails to compile?

interface Father {
    static void method() { }
}

interface Mother {
    default void method() { }
}

interface Child extends Father, Mother {
    static void method() { }
}

Per my understanding, each static method belongs to its specific Class, hence, why when Child interface defines static void method() { } the compiler gives the following error?

method() in Child clashes with method() in Mother overriding method is static

Should not Child keep the default method implementation from Mother while allowing Father and Child with its own Static methods like: Father.method() and Child.method() ?

Pshemo :

Father is not a problem here since static methods from interfaces are not inherited (for instance List.of(..) can't be invoked via ArrayList.of(..)) so there is no overriding/hiding which also means no collisions.

Because of that we can safely write

interface Father {
    static void method() { } 
}
interface Child extends Father {
    static void method() { } 
}

Problem is default void method() { } method from Mother interface which is inherited to Child which means that after

interface Child extends Father, Mother { 
    static void method() { } 
}

you would end up with interface which would have two method() versions: static and non-static (default)

interface Child extends Father, Mother { 
    static void method() { } 
    default void method() { } //inherited from Mother
}

But why is that a problem?

Imagine you want to add another method to Child interface which will call method()

interface Child extends Father, Mother { 
    static void method() { } 
    default void method() { } //inherited from Mother
    default void demo(){
        method(); //which code block should be executed?
    }
}

Should it execute code from static method() or from default method()? Compiler wouldn't be able to decide.

Although this situation could be solved by using

  • Child.method() for static method,
  • this.method() for default method (yes, it wound't be ambiguous because static method wouldn't be inherited by class of which this would be instance),

point is to prevent such problems in the first place. That is why we are required to not have static and non-static methods with same signature (name+parameterTypes) in one place (defined or inherited).

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=115408&siteId=1
Recommended