Lambda FAQ_16.钻石问题

来源:互联网 发布:网络规划工程师 编辑:程序博客网 时间:2024/04/27 09:16

钻石问题

“钻石问题”是允许多继承所带来的问题。对于允许状态的多继承语言来说(比如C++)这是一个严重的问题。但是,在Java中是不允许类的多继承,仅仅允许接口多继承,所以是不包含状态的。

考虑下面的场景:
interface A {        default void m() { ... }            }interface B extends A {}interface C extends A {}class D implements B, C {}

根据上一章节说明的默认方法选择规则,在类似这种场景中Java会有一种简单直接的解释方法。

如上代码所示的这种场景,D所继承的m方法的实现是没有歧义的,因为m方法只在A中定义。如果情况改变一下,B也声明了方法m的实现,那么D就会应用“最明确的实现”这一规则。但是如果B和C都提供了m的默认实现,那么就会产生歧义,这时D就必须提供m的复写声明,可能是使用`X.super.m(..)`这种语法来显示的选择一个继承的实现。这三种情况都在上一章节的“方法决议规则”中明确说明了。

默认方法和Java中所有的方法一样,是虚拟的。这个有时会产生一些令人惊讶的结果。例如给定下面的声明:
interface A {    default void m() { System.out.println("hello from A"); }}interface B extends A {    default void m() { System.out.println("hello from B"); }}interface C extends A {}class D implements B, C {}

下面的代码:
C c = new D();c.m();
将会打印出hello from B。静态的类型C并不重要,关键的是实际的类型是D,而D最明确的m声明是从继承B而来的。

原文地址

原文地址

0 0
原创粉丝点击