If a type implements two interfaces, and each interface define a method that has identical signature, then in effect there is only one method, and they are not distinguishable. If, say, the two methods have conflicting return types, then it will be a compilation error. This is the general rule of inheritance, method overriding, hiding, and declarations, and applies also to possible conflicts not only between 2 inherited interface methods, but also an interface and a super class method, or even just conflicts due to type erasure of generics.
兼容性的例子
下面是一个例子,其中有一个接口Gift,它有一个present()方法(在这里,赠送礼物),还有一个接口Guest,它也有一个present()方法(在这里,客人出现而不是缺席)。
得体的强尼既是礼物,也是客人。
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!!!"
}
}
上面的代码片段编译并运行。
注意,只有一个@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"
}
这进一步重申了从接口继承成员必须遵守成员声明的一般规则。这里Gift和Guest定义的present()返回类型不兼容:一个为void,另一个为boolean。由于同样的原因,你不能在一个类型中使用void present()和boolean present(),这个例子会导致编译错误。
总结
您可以继承@ override等效的方法,这取决于方法重写和隐藏的通常要求。由于它们是@ override等效的,实际上只有一个方法可以实现,因此没有什么可以区分/选择的。
编译器不必识别哪个方法对应哪个接口,因为一旦确定它们是@ override等效的,它们就是相同的方法。
解决潜在的不兼容性可能是一项棘手的任务,但这完全是另一个问题。
参考文献
JLS 8.4.2方法签名
JLS 8.4.8继承、重写和隐藏
JLS 8.4.8.3覆盖和隐藏的要求
JLS 8.4.8.4继承具有重写等效签名的方法
一个类可以继承多个具有重写等效签名的方法。