关于java:接口的多重继承歧义

Multiple Inheritance Ambiguity with Interface

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

1
2
3
4
5
   A
  / \
 B   C
  \ /
   D

这个问题描述了类D的一个模糊情况。如果类A有一个方法,并且B和/或C中的任何一个都重写了该方法,那么D重写的是哪个版本的方法?

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


钻石问题只适用于实现继承(在Java 8之前的所有版本的Java中,EDCOX1×0)。它不适用于API继承(在Java 8之前的所有版本的Java中,EDCOX1×1)。

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

在Java 7和下面,继承实现代码的惟一方法是通过最多0个父关键字来限制父进程的关键字。因此,不存在多重实现继承和菱形问题。

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


用接口添加关于Java8多重继承的现有答案(又名Java如何仍然避免菱形问题):

要遵循三条规则:

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

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

  • enter image description here

  • 如果不是上面的情况,继承类必须显式地声明它使用的方法实现(否则它不会编译)。
  • enter image description here


    在Java 8中引入接口的默认方法中,可能会出现多重继承相关问题,有3种情况:

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

    2-当类实现两个接口,并且两个接口都具有相同的默认方法时,同时该类没有重写该方法,则将引发错误。

    3-如果一个接口扩展另一个接口,并且两个接口具有相同的默认方法,则继承接口默认方法将优先。

    在这里阅读更多关于它的信息。


    Java克服了这个问题,即使接口可以有默认的方法实现,因为缺省实现要么是明确的(在类EDCOX1中引用3),要么通过某种规则来解决(当EDCOX1类4或类EDCOX1 5)覆盖从EDCOX1类3执行时的实现时,见下文)。

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

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

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

    请参见:Java 8新的默认接口模型是如何工作的(包括钻石、多重继承和优先权)?


    Java不支持多重继承,所以钻石问题不会出现。如果B&C是接口,那么接口中没有实现。即使B&C重写接口A中的方法(不能是类),这些方法也将具有相同的签名。对于要使用哪种实现没有歧义,因为没有实现。


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