如何处理菱形问题?
“菱形问题”是一种由于多重继承引起的歧义性问题。对于像c++这类允许状态多重继承的语言来说是一个严重的问题。然而在java中只能在接口上而不允许类的多重继承,因此不会包含状态。
考虑下面的情况:
[img]http://www.lambdafaq.org/wp-content/uploads/Diamond.png[/img]
上一节给出的缺省方法选择规则为这种情况及其变化提供了一个直观的解释。
在初始情况下(以上代码),D继承的方法m的实现没有歧义性,其由A定义,没有其他可能性。如果情况改变,B现在也声明了m的缺省实现,那么D继承的m的实现遵循“最具体实现”原则。但是,如果B和C都提供缺省实现,那么它们将发生冲突,且D必须提供一个覆盖声明,可能使用语法X.super.m(...)来显式选择继承其一。所有这三种情况正如先前的解释都被方法解析规则所清楚地涵盖。
缺省方法是虚拟的,就像Java中的所有方法。这有时会导致意想不到的结果。给定声明:
代码
将打印 hellow from B。C的静态类型并不重要;关键是它是D的实例,其m的最具体的版本继承自B。
原文链接:http://www.lambdafaq.org/what-about-the-diamond-problem/
“菱形问题”是一种由于多重继承引起的歧义性问题。对于像c++这类允许状态多重继承的语言来说是一个严重的问题。然而在java中只能在接口上而不允许类的多重继承,因此不会包含状态。
考虑下面的情况:
interface A {
default void m() { ... }
}
interface B extends A {}
interface C extends A {}
class D implements B, C {}
[img]http://www.lambdafaq.org/wp-content/uploads/Diamond.png[/img]
上一节给出的缺省方法选择规则为这种情况及其变化提供了一个直观的解释。
在初始情况下(以上代码),D继承的方法m的实现没有歧义性,其由A定义,没有其他可能性。如果情况改变,B现在也声明了m的缺省实现,那么D继承的m的实现遵循“最具体实现”原则。但是,如果B和C都提供缺省实现,那么它们将发生冲突,且D必须提供一个覆盖声明,可能使用语法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();
将打印 hellow from B。C的静态类型并不重要;关键是它是D的实例,其m的最具体的版本继承自B。
原文链接:http://www.lambdafaq.org/what-about-the-diamond-problem/