Why does order of implementing Interfaces (with default methods) matter in Java 8?
Asked Answered
C

2

15

As we all know, multiple interfaces can implemented in Java. Does the order of their implementation matter? I mean, is implementing B, C is same as C, B in Java 8? My tests show order does matter - but can anyone explain the logic behind this?

public interface A {
    public default void display() {
        System.out.println("Display from A");
    }
}

public interface B extends A {
    public default void display() {
        System.out.println("Display from B");
    }
}

public interface C extends A {
    public void display();
}

public interface D extends B, C {

}

The above code works fine. If I change the order B, C to C, B, it will give an error: The default method display() inherited from B conflicts with another method inherited from C.

public interface D extends C, B {

}

Edit

I am using Eclipse(Mars). JDK jdk1.8.0_51. JRE jre1.8.0_60.

Chappie answered 19/9, 2015 at 2:38 Comment(6)
Am I missing something? If I understood correctly, you said you get an error when using one order and you don't when using a different order, which means the order makes a difference, which means you answered your own question.Aniela
Yes, I am getting the difference. I just want to know if there is any reason behind this?Chappie
You should get the same error regardless of the order (meaning, in both cases). Please check again!Bork
#31617801Dev
nope; compile error either way...Tonietonight
No, there isn't.. The error is only in one way.Chappie
T
8

There should be an error message either way. When I use jdk 1.8.0_31 I get the following error no matter the order of interfaces:

The default method display() inherited from A.B conflicts with another method inherited from A.C

The solution is to either override display() in D even to just tell the compiler which super class's implementation to use:

public interface D extends B, C {
    default void display(){
        B.super.display();
    }
}

Or remake display() abstract

interface D extends B, C {
    public void display();
}

If you are indeed getting this error using a higher version than me, then it might be worth submitting a bug report?

Tendency answered 19/9, 2015 at 3:38 Comment(2)
D can also re-assert display() as abstract.Tonietonight
Error(it is the correct behavior) you see is same in 1.8.0_40. Order makes no difference.Unequivocal
H
6

results from javac (all versions 1.8.0_x):

error: interface D inherits abstract and default for display() from types B and C

resuls from ecj 4.4:

The default method display() inherited from B conflicts with another method inherited from C

resuls from ecj >= 4.4.1:

NO ERROR

Still ecj >= 4.4.1 correctly reports the error if order in D's extends clause is changed.

I conclude that this is a bug in Eclipse, which got introduced in 4.4.1. I've filed bug 477891 to follow up.

Edit: bug 477891 has been fixed in Milestone 3 towards Eclipse 4.6 (GA: June 2016).

Hen answered 20/9, 2015 at 12:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.