Problem:
我们知道 Java 不允许扩展多个类,因为这会导致钻石问题 https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem编译器无法决定使用哪个超类方法。使用接口默认方法钻石问题被介绍于Java 8。也就是说,因为如果一个类实现两个接口,每个接口都定义相同的默认方法,并且实现类不重写公共默认方法,则编译器无法决定选择哪个实现。
解决方案:
Java 8需要为多个接口实现的默认方法提供一种实现。因此,如果一个类要实现上述两个接口,它就必须提供公共默认方法的实现。否则编译器会抛出编译时错误。
问题:
为什么这个解决方案不适用于通过重写子类引入的公共方法来实现多类继承?
您没有正确理解钻石问题(当然,维基百科文章的当前状态并没有充分解释它)。如此图所示,
钻石问题发生,当同一个班级通过不同的继承路径被多次继承。对于接口来说这不是问题(而且从来都不是问题),因为它们只定义一个契约,多次指定相同的契约没有什么区别。
主要问题不在于方法,而在于data那种超级类型。如果实例状态为A
在这种情况下存在一次或两次?如果有一次,C
and B
可能有不同的、相互冲突的约束A
的实例状态。这两个类也可能假设完全控制A
的状态,即不考虑具有相同访问级别的其他类。如果有两个不同的A
状态,扩大转换D
参考一个A
引用变得不明确,因为A
可以是这个意思。
接口不存在这些问题,因为它们根本不携带实例数据。他们也(几乎)没有可访问性问题,因为他们的方法总是public
。允许default
方法,不会改变这一点,因为default
方法仍然不访问实例变量,而仅使用接口方法进行操作。
当然,也有一种可能是B
and C
宣布default
具有相同签名的方法,导致必须解决的歧义D
。但即便如此,当没有A
,即根本没有“钻石”。所以这个场景不是“钻石问题”的正确例子。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)