Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 default method inheritance

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

like image 364
aiguy Avatar asked May 12 '16 20:05

aiguy


People also ask

Are default methods inherited in Java?

Default methods and abstract methods in interfaces are inherited like instance methods. However, when the supertypes of a class or interface provide multiple default methods with the same signature, the Java compiler follows inheritance rules to resolve the name conflict.

Can we inherit the default method?

Default methods in Java 8 can be viewed as a form of multiple inheritance (except that attribute can not be inherited). Consider the example below, the Button class implements two interfaces - Clickable and Accessible. Each interface defines a default method.

What is the default method of Java 8?

Java 8 introduces default method so that List/Collection interface can have a default implementation of forEach method, and the class implementing these interfaces need not implement the same.

Can we inherit default method of interface?

Extending Interfaces That Contain Default Methods Not mention the default method at all, which lets your extended interface inherit the default method.


1 Answers

This behavior is specified using almost your exact example in JLS 9.4.1, just with some names changed around:

interface Top {
    default String name() { return "unnamed"; }
}
interface Left extends Top {
    default String name() { return getClass().getName(); }
}
interface Right extends Top {}

interface Bottom extends Left, Right {}

Right inherits name() from Top, but Bottom inherits name() from Left, not Right. This is because name() from Left overrides the declaration of name() in Top.

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.

like image 168
Louis Wasserman Avatar answered Sep 20 '22 19:09

Louis Wasserman