接口的多重inheritance歧义

我们都知道有关多重遗传的钻石问题 –

A / \ BC \ / D 

这个问题描述了D类的模糊情况。 如果A类有一个方法并且B和/或C两个/都覆盖了该方法,则D覆盖哪个版本的方法?

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

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

由于具有匹配类型签名的接口方法是兼容的,因此如果您inheritance两次相同的方法签名,则没有菱形问题:匹配方法签名只是简单地合并。 (如果类型签名不一样,那么你也没有钻石问题。)

在Java 7及更低版本中,inheritance实现代码的唯一方法是使用extends关键字,该关键字最多只能限制一个父级。 因此,没有多重实现inheritance,并且不存在钻石问题。

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

通过接口添加有关Java8多重inheritance的现有答案(也就是Java如何仍然避免钻石问题):

有三条规则要遵循:

  1. 一堂课总是胜利 。 类自己的方法实现优先于接口中的默认方法。

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

在此处输入图像描述

  1. 如果不是这种情况,inheritance类必须显式声明它正在使用哪个方法实现(否则它将无法编译)

在此处输入图像描述

Java克服了这个问题,即使接口可以有方法的默认实现,因为默认实现是明确的A类中A 那个 )或者情境是通过某种规则解决的 (当B类或C类覆盖A类的实现时,见下文)。

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

  • 实例方法优于接口默认方法。
  • 已忽略其他候选项的方法将被忽略。 当超类型共享共同的祖先时,可能会出现这种情况

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

另请参阅: Java 8的新默认界面模型如何工作(包括菱形,多重inheritance和优先级)?

使用Java 8中引入的接口中的默认方法,可能会出现多个inheritance相关的问题,有3种情况 –

1-如果实现类重写默认方法并为默认方法提供自己的function,则类的方法优先于接口默认方法。

2 – 当类实现两个接口并且两者都具有相同的默认方法时,类也不会覆盖该方法,然后将抛出错误。

3 – 如果接口扩展另一个接口并且两者都具有相同的默认方法,则inheritance接口缺省方法将优先。

在这里阅读更多相关信息。

Java不支持多重inheritance,因此不会出现钻石问题。 如果B&C是接口,则接口中没有实现。 即使B&C覆盖接口A中的方法(不能是类),方法也会有相同的签名。 关于使用哪种实现没有歧义,因为没有实现。

Interesting Posts