具有接口的多重继承模糊性

我们都知道关于多重继承的钻石问题——

   A
  / \
 B   C
  \ / 
   D

此问题描述了类 的模糊情况。如果类有一个方法,并且两者兼而有之,并且/或重写该方法,那么哪个版本的方法会重写?DABCD

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


答案 1

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

由于具有匹配类型签名的接口方法是兼容的,因此,如果两次继承相同的方法签名,则不会出现菱形问题:匹配方法签名只是合并。(如果类型签名不相同,那么您也没有菱形问题。

在 Java 7 及更低版本中,继承实现代码的唯一方法是通过关键字,该关键字最多只能使用一个父级。因此不存在多重实现继承,钻石问题也不存在。extends

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


答案 2

为了补充关于Java8多重继承与接口的现有答案(又名Java如何仍然避免钻石问题):

有三条规则需要遵循:

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

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

enter image description here

  1. 如果不是上述情况,继承类必须显式声明它正在使用的方法实现(否则它不会编译)

enter image description here