java 接口的多重继承歧义

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29758213/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 15:52:16  来源:igfitidea点击:

Multiple Inheritance Ambiguity with Interface

javaoopinheritanceinterfacediamond-problem

提问by Razib

We all know about the diamond problemregarding multiple inheritance -

我们都知道关于多重继承的菱形问题——

   A
  / \
 B   C
  \ / 
   D

This problem describe an ambiguous situation for class D. If class Ahas a method and both/either of Band/or Coverride the method then which version of method does Doverride?

这个问题描述了 class 的一种模棱两可的情况D。如果类A有一个方法并且两个/一个B和/或C覆盖该方法,那么哪个版本的方法会D覆盖?

Is this problem also applicable for interfaces in Java? If not, how do Java interfaces overcome this problem?

这个问题是否也适用于 Java 中的接口?如果没有,Java 接口如何克服这个问题?

采纳答案by Daniel Pryden

The diamond problem only applies to implementationinheritance (extendsin all versions of Java prior to Java 8). It doesn't apply to APIinheritance (implementsin all versions of Java prior to Java 8).

菱形问题仅适用于实现继承(extends在 Java 8 之前的所有 Java 版本中)。它不适用于API继承(implements在 Java 8 之前的所有 Java 版本中)。

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 implementationcode was via the extendskeyword, which restricts to at most one parent. Therefore there is no multiple implementation inheritance and the diamond problem does not exist.

在 Java 7 及以下版本中,继承实现代码的唯一方法是通过extends关键字,该关键字最多只能有一个父级。因此不存在多重实现继承,也不存在菱形问题。

Java 8 adds a new wrinkle because it allows interfaces to have implementation code. 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.

Java 8 增加了一个新问题,因为它允许接口具有实现代码。当您使用具有匹配签名的方法实现多个接口时,它仍然通过简单地回退到以前的行为(没有实现继承)来逃避钻石问题。

回答by Andrejs

To add to existing answers about Java8 multiple inheritance with interfaces (a.k.a. how Java still avoids the diamond problem):

要添加有关 Java8 多继承接口的现有答案(也就是 Java 如何仍然避免菱形问题):

There are three rules to follow:

有以下三个规则需要遵守:

  1. A class always wins. Class's own method implementation takes priority over default methods in Interfaces.

  2. If class doesn't have any: the most specific interface wins

  1. 一个班总是赢。类自己的方法实现优先于接口中的默认方法。

  2. 如果类没有任何:最具体的接口获胜

enter image description here

enter image description here

  1. If above is not the case, inheriting class has to explicitly statewhich method implementation it's using (otherwise it won't compile)
  1. 如果上述情况并非如此,则继承类必须明确说明它正在使用哪个方法实现(否则将无法编译)

enter image description here

enter image description here

回答by olovb

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 Bor class Coverrides the implementation from class A, see below).

Java 克服了这个问题,即使接口可以有方法的默认实现,因为默认实现要么是明确的(在 class 中的A),要么通过某种规则解决了这种情况(当 classB或 classC覆盖了class的实现时A,见下文)。

When the supertypes of a class or interface provide multiple default methods with the same signature:

当类或接口的超类型提供多个具有相同签名的默认方法时:

  • Instance methods are preferred over interface default methods.
  • Methods that are already overridden by other candidates are ignored. This circumstance can arise when supertypes share a common ancestor.
  • 实例方法优于接口默认方法。
  • 已经被其他候选者覆盖的方法将被忽略。当超类型共享一个共同的祖先时,就会出现这种情况

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. You must explicitly override the supertype methods. In this case you could invoke any of the of the default implementations with the super keyword.

但是,如果两个或多个独立定义的默认方法发生冲突,或者默认方法与抽象方法发生冲突,那么 Java 编译器会产生编译器错误。您必须显式覆盖超类型方法。在这种情况下,您可以使用 super 关键字调用任何默认实现。

See also: How does Java 8' new default interface model works (incl. diamond, multiple inheritance, and precedence)?

另请参阅:Java 8 的新默认接口模型如何工作(包括菱形、多重继承和优先级)?

回答by infoj

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-如果一个接口扩展了另一个接口并且两者具有相同的默认方法,则继承的接口默认方法将优先。

read more about it here.

在此处阅读更多相关信息。

回答by vinay

Java doesn't support multiple inheritance, so the diamond problem doesn't arise. If B & C are interfaces, then there is no implementation in the interfaces. Even if B & C override the method in interface A (cannot be a class), the methods will have same signature. There is no ambiguity regarding which implementation to use, because there is no implementation.

Java 不支持多重继承,所以不会出现菱形问题。如果 B & C 是接口,则接口中没有实现。即使 B & C 覆盖了接口 A 中的方法(不能是类),这些方法也将具有相同的签名。关于使用哪个实现没有歧义,因为没有实现。

回答by SumataPatil

Interfaces having dummy declarations and they won't have implementations hence no ambiguity problem.

具有虚拟声明的接口,它们不会有实现,因此没有歧义问题。