使用相同的方法在类中实现两个接口。覆盖哪种接口方法? [英] Implementing two interfaces in a class with same method. Which interface method is overridden?
问题描述
两个具有相同方法名称和签名的接口。但是由单个类实现,那么编译器将如何识别哪个方法适用于哪个接口?
Two interfaces with same method names and signatures. But implemented by a single class then how the compiler will identify the which method is for which interface?
Ex:
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;
}
}
推荐答案
如果一个类型实现两个接口,每个接口
定义一个具有相同签名的方法,然后实际上只有一个方法,并且它们是不可区分的。例如,如果这两种方法具有冲突的返回类型,那么它将是编译错误。这是继承,方法重写,隐藏和声明的一般规则,并且还适用于不仅在2个继承的接口
方法之间的可能冲突,而且还适用于 interface
和一个超级类
方法,甚至只是由于类型擦除泛型而产生的冲突。
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.
这是一个示例,其中有一个界面礼物
,它有一个 present()
方法(如赠送礼物),还有一个界面Guest
,它还有一个 present()
方法(如同客人在场但不在场)。
Here's an example where you have an interface Gift
, which has a present()
method (as in, presenting gifts), and also an interface Guest
, which also has a present()
method (as in, the guest is present and not absent).
可呈现的约翰尼
既是礼物
又是来宾
。
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!!!"
}
}
以上代码段编译并运行。
The above snippet compiles and runs.
请注意只有一个 @Override
必要!!! 。这是因为 Gift.present()
和 Guest.present()
是 @Override
-equivalent( JLS 8.4.2 )。
Note that there is only one @Override
necessary!!!. This is because Gift.present()
and Guest.present()
are "@Override
-equivalent" (JLS 8.4.2).
因此, johnny
只有一个实现 present()
,无论你如何对待 johnny
,无论是否为礼物
或作为访客
,只有一种方法可以调用。
Thus, johnny
only has one implementation of present()
, and it doesn't matter how you treat johnny
, whether as a Gift
or as a Guest
, there is only one method to invoke.
以下是两个继承方法不是 @Override的示例
-equivalent:
Here's an example where the two inherited methods are NOT @Override
-equivalent:
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"
}
这进一步重申从接口继承成员
必须遵守成员声明的一般规则。这里我们有礼物
和访客
定义 present()
不兼容的返回类型:一个 void
另一个 boolean
。出于同样的原因,你不能在一种类型中使用 void present()
和 boolean present()
,此示例导致编译错误。
This further reiterates that inheriting members from an interface
must obey the general rule of member declarations. Here we have Gift
and Guest
define present()
with incompatible return types: one void
the other boolean
. For the same reason that you can't an void present()
and a boolean present()
in one type, this example results in a compilation error.
您可以继承 @Override
-equivalent的方法,这取决于方法覆盖和隐藏的常规要求。由于它们 ARE @Override
-equivalent,实际上只有一种方法可以实现,因此无需区分/选择。
You can inherit methods that are @Override
-equivalent, subject to the usual requirements of method overriding and hiding. Since they ARE @Override
-equivalent, effectively there is only one method to implement, and thus there's nothing to distinguish/select from.
编译器不必识别哪个接口的方法,因为一旦确定它们是 @Override
- 等价,它们是相同的方法。
The compiler does not have to identify which method is for which interface, because once they are determined to be @Override
-equivalent, they're the same method.
解决潜在的不兼容问题可能是一项棘手的任务,但这完全是另一个问题。
Resolving potential incompatibilities may be a tricky task, but that's another issue altogether.
- JLS 8.4.2方法签名
- JLS 8.4.8继承,覆盖和隐藏
- 覆盖和JLS 8.4.8.3要求隐藏
- JLS 8.4.8.4使用Override-E继承方法quivalent签名
- 类可以使用覆盖等效签名继承多个方法。
- JLS 8.4.2 Method Signature
- JLS 8.4.8 Inheritance, Overriding, and Hiding
- JLS 8.4.8.3 Requirements in Overriding and Hiding
- JLS 8.4.8.4 Inheriting Methods with Override-Equivalent Signatures
- "It is possible for a class to inherit multiple methods with override-equivalent signatures."
这篇关于使用相同的方法在类中实现两个接口。覆盖哪种接口方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!