接口的多重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如何仍然避免钻石问题):
有三条规则要遵循:
-
一堂课总是胜利 。 类自己的方法实现优先于接口中的默认方法。
-
如果类没有: 最具体的接口获胜
- 如果不是这种情况,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中的方法(不能是类),方法也会有相同的签名。 关于使用哪种实现没有歧义,因为没有实现。