带接口的多重继承歧义

Raz*_*zib 23 java oop inheritance interface diamond-problem

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

   A
  / \
 B   C
  \ / 
   D
Run Code Online (Sandbox Code Playgroud)

这个问题描述了课堂的模糊情况D.如果类A有一个方法,并且/ B和/或C覆盖方法,那么哪个版本的方法会D覆盖?

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

Dan*_*den 19

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

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

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

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

  • @supercat * FYI:*如果B和C都具有默认实现,而D没有覆盖,则JVM将抛出IncompatibleClassChangeError:冲突的默认方法。它既是编译错误,又是运行时错误。 (2认同)

And*_*ejs 6

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

有三条规则要遵循:

  1. 班级总是胜利.类自己的方法实现优先于接口中的默认方法.

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

在此输入图像描述

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

在此输入图像描述