实现两个声明相同方法的接口时出现意外的编译器错误 - (一个抽象和一个默认值)

时间:2018-02-22 15:31:25

标签: java inheritance interface abstract-class name-clash

我想知道为什么以下(下面的示例1 )给我一个编译错误,说明......

  

'ClassA从类型Interface1和Interface2'

继承test()的抽象和默认值

...如果我将Interface1更改为抽象类并让AClass扩展它,  (虽然仍在实现Interface2),它的行为与我期望的一样(没有编译器错误)。

我的理解是抽象方法的优先级高于默认方法。换句话说,我希望 example 1 能够编译,就像 example2 那样 - 以及从AClass派生的任何具体类必须为测试提供实现() 方法。在这两个例子中,如果我从ClassA的定义中删除'abstract',我会得到编译器错误(如预期的那样),因为我没有提供该实现。为什么,当AClass是抽象的时,它在实现2个接口时不会编译,但是在扩展ASupClass和实现Interface2时呢?为什么不同?

代码示例1(带2个接口)

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

interface Interface1{    
    public abstract String test();    
}

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

代码示例2(带有1个抽象类和1个接口)

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

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

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

1 个答案:

答案 0 :(得分:0)

示例1

一个类不能实现两个接口,这些接口公开具有相同签名的方法。这与编译器有关,无法知道该类的哪个方法正在实现。如果方法被声明为抽象默认并不重要,实际上认为必须实现抽象方法,也可以实现默认方法,从而导致模棱两可。

示例2

相反,第二个例子编译,因为没有歧义。默认方法为 int result = digitCount(2, 1, 0); 方法提供了实现,因此不强制具体类遵守与接口的约定,而抽象类将默认实现理解为其test()方法的实现。