我们都知道有关多重继承的diamond problem -
A
/ \
B C
\ /
D
此问题描述了类D
的模糊情况。如果类A
有一个方法,并且B
和/或C
中的任何一个都覆盖了该方法,则D
覆盖哪个版本的方法?
此问题是否也适用于Java中的接口?如果没有,Java接口如何克服这个问题?
答案 0 :(得分:17)
菱形问题仅适用于Java 8之前的所有Java版本中的实现继承(extends
)。它不适用于Java 8之前的所有Java版本中的 API 继承(implements
)。
由于具有匹配类型签名的接口方法是兼容的,因此如果您继承两次相同的方法签名,则不存在菱形问题:匹配方法签名只是简单地合并。 (如果类型签名不相同,那么你也没有钻石问题。)
在Java 7及更低版本中,继承实现代码的唯一方法是使用extends
关键字,该关键字最多只限制一个父级。因此,没有多重实现继承,并且钻石问题不存在。
Java 8增加了一个新的皱纹,因为它允许接口具有实现代码。当您使用具有匹配签名的方法实现多个接口时,它仍然可以通过简单地回退到先前的行为(没有实现继承)来逃避钻石问题。
答案 1 :(得分:5)
使用接口添加有关Java8多重继承的现有答案(a.k.a.Java仍然避免钻石问题):
要遵循三条规则:
答案 2 :(得分:3)
Java克服了这个问题,即使接口可以有方法的默认实现,因为默认实现是明确(类A
中的那个)或情况得到解决通过某种规则(当班级B
或班级C
覆盖班级A
的实施时,请参见下文)。
当类或接口的超类型提供多个具有相同签名的默认方法时:
但是,如果两个或多个独立定义的默认方法冲突,或者默认方法与抽象方法冲突,则Java编译器会产生编译器错误。您必须显式覆盖超类型方法。在这种情况下,您可以使用super关键字调用任何默认实现。
答案 3 :(得分:3)
使用Java 8中引入的接口中的默认方法,可能会出现多个继承相关的问题,有3种情况 -
1-如果实现类重写默认方法并为默认方法提供自己的功能,则类的方法优先于接口默认方法。
2 - 当类实现两个接口并且两者都具有相同的默认方法时,类也不会覆盖该方法,然后将抛出错误。
3 - 如果接口扩展另一个接口并且两者都具有相同的默认方法,则继承接口的默认方法优先。
详细了解here。
答案 4 :(得分:2)
Java不支持多重继承,因此钻石问题不会出现。如果B& C是接口,接口中没有实现。即使B& C覆盖接口A中的方法(不能是类),方法将具有相同的签名。关于使用哪种实现没有歧义,因为没有实现。
答案 5 :(得分:0)
具有伪声明的接口,它们将没有实现,因此没有 模棱两可的问题。