[英]Multiple Inheritance Ambiguity with Interface
We all know about the diamond problem regarding multiple inheritance - 我们都知道有关多重遗传的钻石问题 -
A
/ \
B C
\ /
D
This problem describe an ambiguous situation for class D
. 这个问题描述了
D
类的模糊情况。 If class A
has a method and both/either of B
and/or C
override the method then which version of method does D
override? 如果
A
类有一个方法并且B
和/或C
两个/都覆盖了该方法,则D
覆盖哪个版本的方法?
Is this problem also applicable for interfaces in Java? 这个问题是否也适用于Java中的接口? If not, how do Java interfaces overcome this problem?
如果没有,Java接口如何克服这个问题?
The diamond problem only applies to implementation inheritance ( extends
in all versions of Java prior to Java 8). 菱形问题仅适用于实现继承(在Java 8之前的所有Java版本中都有
extends
)。 It doesn't apply to API inheritance ( implements
in all versions of Java prior to Java 8). 它不适用于API继承(在Java 8之前的所有Java版本中
implements
)。
Since interface methods with matching type signatures are compatible, there is no diamond problem if you inherit the same method signature twice: matching method signatures simply coalesce instead. 由于具有匹配类型签名的接口方法是兼容的,因此如果您继承两次相同的方法签名,则不存在菱形问题:匹配方法签名只是简单地合并。 (And if the type signatures aren't the same, then you don't have the diamond problem either.)
(如果类型签名不一样,那么你也没有钻石问题。)
In Java 7 and below, the only way to inherit implementation code was via the extends
keyword, which restricts to at most one parent. 在Java 7及更低版本中,继承实现代码的唯一方法是使用
extends
关键字,该关键字最多只能限制一个父级。 Therefore there is no multiple implementation inheritance and the diamond problem does not exist. 因此,没有多重实现继承,并且钻石问题不存在。
Java 8 adds a new wrinkle because it allows interfaces to have implementation code. Java 8增加了一个新的皱纹,因为它允许接口具有实现代码。 It still escapes the diamond problem by simply falling back to the previous behavior (no implementation inheritance) when you're implementing multiple interfaces with methods that have matching signatures.
当您使用具有匹配签名的方法实现多个接口时,它仍然可以通过简单地回退到先前的行为(没有实现继承)来逃避钻石问题。
To add to existing answers about Java8 multiple inheritance with interfaces (aka how Java still avoids the diamond problem): 通过接口添加有关Java8多重继承的现有答案(也就是Java如何仍然避免钻石问题):
There are three rules to follow: 有三条规则要遵循:
A class always wins . 班级总是胜利 。 Class's own method implementation takes priority over default methods in Interfaces.
类自己的方法实现优先于接口中的默认方法。
If class doesn't have any: the most specific interface wins 如果类没有: 最具体的接口获胜
Java overcomes this problem even though interfaces can have default implementations of methods, because the default implementation is either unambiguous (the one in class A
) or the situation is solved by some rule (when class B
or class C
overrides the implementation from class A
, see below). Java克服了这个问题,即使接口可以有方法的默认实现,因为默认实现是明确的 (
A
类中A
)或者情境是由某些规则解决的 (当B
类或C
类覆盖A
类的实现时,见下文)。
When the supertypes of a class or interface provide multiple default methods with the same signature: 当类或接口的超类型提供具有相同签名的多个默认方法时:
However, if two or more independently defined default methods conflict , or a default method conflicts with an abstract method, then the Java compiler produces a compiler error. 但是, 如果两个或多个独立定义的默认方法冲突 ,或者默认方法与抽象方法冲突,则Java编译器会产生编译器错误。 You must explicitly override the supertype methods .
您必须显式覆盖超类型方法 。 In this case you could invoke any of the of the default implementations with the super keyword.
在这种情况下,您可以使用super关键字调用任何默认实现。
See also: How does Java 8' new default interface model works (incl. diamond, multiple inheritance, and precedence)? 另请参阅: Java 8的新默认接口模型如何工作(包括菱形,多重继承和优先级)?
With default methods in interface introduced in Java 8, multiple inheritance related problem may arise, there are 3 scenarios - 使用Java 8中引入的接口中的默认方法,可能会出现多个继承相关的问题,有3种情况 -
1- If implementing class overrides the default method and provides its own functionality for the default method then the method of the class takes priority over the interface default methods. 1-如果实现类重写默认方法并为默认方法提供自己的功能,则类的方法优先于接口默认方法。
2-When class implements both interfaces and both have the same default method, also the class is not overriding that method then the error will be thrown. 2 - 当类实现两个接口并且两者都具有相同的默认方法时,类也不会覆盖该方法,然后将抛出错误。
3-In case when an interface extends another interface and both have the same default method, the inheriting interface default method will take precedence. 3 - 如果接口扩展另一个接口并且两者都具有相同的默认方法,则继承接口缺省方法优先。
Java doesn't support multiple inheritance, so the diamond problem doesn't arise. Java不支持多重继承,因此不会出现钻石问题。 If B & C are interfaces, then there is no implementation in the interfaces.
如果B&C是接口,则接口中没有实现。 Even if B & C override the method in interface A (cannot be a class), the methods will have same signature.
即使B&C覆盖接口A中的方法(不能是类),方法也会有相同的签名。 There is no ambiguity regarding which implementation to use, because there is no implementation.
关于使用哪种实现没有歧义,因为没有实现。
具有虚拟声明的接口,它们将没有实现,因此没有歧义问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.