0

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

'ClassA 从类型 Interface1 和 Interface2 继承了 test() 的抽象和默认值'

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

我的理解是抽象方法的优先级高于默认方法。换句话说,我希望示例 1能够编译,就像示例 2 一样 - 并且对于从AClass派生的任何具体类都必须为 test() 方法提供实现。在这两个示例中,如果我从 ClassA 的定义中删除“抽象”,则会收到编译器错误(如预期的那样),因为我没有提供该实现。但是,为什么当 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 "";}    
}
4

1 回答 1

0

示例 1

一个类不能实现两个公开具有相同签名的方法的接口。这与编译器有关,无法知道类的哪个方法正在实现。方法声明为abstract还是default无关紧要,实际上认为必须实现抽象方法,也可以实现默认方法,造成歧义。

示例 2

相反,第二个示例编译,因为没有歧义。默认方法提供方法的实现test(),因此具体类不会被迫遵守与接口的约定,抽象类将默认实现理解为其test()方法的实现。

于 2018-02-25T16:35:06.587 回答