0

I'm tying to understand why the following (example 1 below) gives me a compiler error stating that...

'ClassA inherits abstract and default for test() from types Interface1 and Interface2'

...when if I change Interface1 to an abstract class and have AClass extend it, (while still implementing Interface2), it behaves as I would expect (no compiler error).

My understanding is that abstract methods have a higher precedence than that of default methods. In other words, I would expect example 1 to compile, just as example2 does - and for any concrete class(es) derived from AClass to have to provide implementation for the test() method. In both examples, if I remove 'abstract' from ClassA's definition, I get a compiler error (as expected) because I'm not providing that implementation. Why though, when AClass is abstract does it not compile when implementing the 2 interfaces but does when extending ASupClass and implementing Interface2? Why the difference?

Code Example 1 (With 2 interfaces)

abstract class AClass implements Interface1, Interface2{  //Compiler error
}

interface Interface1{    
    public abstract String test();    
}

interface Interface2{
    default String test(){return "";}    
}

Code Example 2 (with 1 abstract class and 1 interface)

abstract class AClass extends ASupClass implements Interface2{ //No compiler error
}

abstract class ASupClass{    
    public abstract String test();    
}

interface Interface2{
    default String test(){return "";}    
}
Zippy
  • 3,826
  • 5
  • 43
  • 96

1 Answers1

0

Example 1

A class can't implement two interfaces that expose methods that have the same signature. That's related to the compiler, that can't know which method of the class is implementing. It doesn't matter if a method is declared abstract or default, in fact thought that an abstract method must be implemented, a default method can be also implemented, causing the ambiguity.

Example 2

Instead,the second example compiles because there is no ambiguity. The default method provides an implementantion to test() method, so the concrete class is not forced to respect the contract with the interface and the abstract class understands the default implementantion as the implementantion to itstest() method.

Community
  • 1
  • 1
Jul10
  • 503
  • 7
  • 19
  • Why is there ambiguity in example 1 but not example 2? It doesn't make much sense to me. In both examples, there is only one implementation (in the default method). If anything I would expect the compiler to tell me I need to implement the abstract method as abstract methods take precedence over default methods, but I still can't understand why there is a difference between the 2 examples... both have one abstract and one default method so the ambiguity (or lack of) should be the same... regardless :-/ – Zippy Feb 27 '18 at 02:14
  • By definition an interface as only abstract methods, default methods have been introduced from Java 8 for retrocompatibility purposes.So the compiler essentially don't make a strong difference beetween abstract or default methods. So, when a class implements `test()` , the compiler can't say if you're providing an implementantion for interface 1 or 2. Example 2 doesn't suffer this problem because it involves inheritance.A concrete class can extend the abstract class and implement the interface because it respects the contract with interface and provides implementation to abstract class' method – Jul10 Feb 27 '18 at 19:30