如何解决用相同的方法在一个类中实现两个接口哪个接口方法被覆盖?
如果一个类型实现了两个接口,并且每个接口都interface
定义了一个签名相同的方法,那么实际上只有一个方法,并且它们是不可区分的。例如,如果这两个方法的返回类型冲突,那么这将是一个编译错误。这是继承、方法覆盖、隐藏和声明的一般规则,并且不仅适用于两个继承interface
方法之间的可能冲突,也适用于一个interface
和一个超级class
方法之间的冲突,甚至只是由于泛型的类型擦除引起的冲突。
兼容性示例
这是一个示例,其中您有一个interface Gift
,它有一个present()
方法(例如,赠送礼物),还有一个interface
Guest
,它也有一个present()
方法(例如,客人在场并且没有缺席)。
Presentable johnny
既是 aGift
又是 a 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!!!"
}
}
上面的代码片段编译并运行。
请注意, @Override
. 这是因为Gift.present()
和Guest.present()
是“
-等价的@Override
”(JLS
8.4.2)。
因此,johnny
,present()
无论您如何对待johnny
,无论是作为 aGift
还是作为 aGuest
,都只有一种方法可以调用。
不兼容示例
这是一个示例,其中两个继承的方法不@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"
}
这进一步重申了从 an
继承成员interface
必须遵守成员声明的一般规则。在这里,我们有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 继承具有覆盖等效签名的方法
- “一个类可以继承多个具有重写等效签名的方法。”
解决方法
具有相同方法名称和签名的两个接口。但是由单个类实现,那么编译器将如何识别哪个方法用于哪个接口?
前任:
interface A{
int f();
}
interface B{
int f();
}
class Test implements A,B{
public static void main(String... args) throws Exception{
}
@Override
public int f() { // from which interface A or B
return 0;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。