如果一个类型实现了两个接口,并且每个interface 都定义了一个具有相同签名的方法,那么实际上只有一个方法,并且它们是不可区分的。如果,比如说,这两个方法有冲突的返回类型,那么这将是一个编译错误。这是继承、方法覆盖、隐藏和声明的一般规则,不仅适用于 2 个继承的 interface 方法之间可能发生的冲突,还适用于 interface 和超级 class 方法之间可能发生的冲突,甚至只是冲突由于泛型的类型擦除。
兼容性示例
这是一个示例,其中您有一个 interface Gift,它有一个 present() 方法(如赠送礼物),还有一个 interface Guest,它也有一个 present() 方法(如,客人在场并且不缺席)。
Presentable johnny 既是Gift 又是Guest。
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { void present(); }
interface Presentable extends Gift, Guest { }
public static void main(String[] args) {
Presentable johnny = new Presentable() {
@Override public void present() {
System.out.println("Heeeereee's Johnny!!!");
}
};
johnny.present(); // "Heeeereee's Johnny!!!"
((Gift) johnny).present(); // "Heeeereee's Johnny!!!"
((Guest) johnny).present(); // "Heeeereee's Johnny!!!"
Gift johnnyAsGift = (Gift) johnny;
johnnyAsGift.present(); // "Heeeereee's Johnny!!!"
Guest johnnyAsGuest = (Guest) johnny;
johnnyAsGuest.present(); // "Heeeereee's Johnny!!!"
}
}
以上sn -p编译运行。
注意只有一个@Override必要的!!!.这是因为 Gift.present() 和 Guest.present() 是“@Override-等价物” (JLS 8.4.2)。
因此,johnny只有一种实现present(),无论您如何对待johnny,无论是作为Gift还是作为Guest,都只有一个方法可以调用。
不兼容示例
这是一个示例,其中两个继承的方法不是 @Override-等效的:
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { boolean present(); }
interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
// "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible;
// both define present(), but with unrelated return types"
}
这进一步重申,从 interface 继承成员必须遵守成员声明的一般规则。这里我们有Gift和Guest定义present()不兼容的返回类型:一个void另一个boolean。出于与您不能在一种类型中使用 void present() 和 boolean present() 相同的原因,此示例会导致编译错误。
概括
您可以继承 @Override 等效的方法,但要满足方法覆盖和隐藏的通常要求。自从他们是@Override-等效,实际上只有一种方法可以实现,因此没有什么可以区分/选择的。
编译器不必识别哪个方法适用于哪个接口,因为一旦它们被确定为 @Override-等价物,它们就是相同的方法。
解决潜在的不兼容性可能是一项棘手的任务,但这完全是另一个问题。
参考