Lambda FAQ_16.钻石问题

18 篇文章 0 订阅
17 篇文章 0 订阅

钻石问题

“钻石问题”是允许多继承所带来的问题。对于允许状态的多继承语言来说(比如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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值