默认方法和多重继承

最近卢卡斯JOOQ埃德尔发布和文章有关嵌套类及其使用。 这是一个有趣的话题,他的文章一如既往地有趣并且值得一读。 我只同意一个简短的声明,我们有一个简短的回复链,导致默认方法,以及为什么不能有类似的东西

class Outer {
    <non-static> interface Inner {
        default void x() {
            System.out.println(Outer.this.toString());
        }
    }
 
    Inner2 y() {
        return new Inner2();
    }
}
 
class Inner2 implements Inner {
}
 
// This would now print Outer.toString()
// to the console
new Outer().y().x();

在Java中。 可以这么说,在上面的代码中,内部接口的默认方法将引用包围该接口的实例。 我认为“答复”不是最佳的沟通方式,因为最初的话题有所不同,我现在就去谈谈。

什么是默认方法

你可能知道。 如果不是google,或者阅读我的文章Java 8默认方法:可以做什么和不能做什么? 以及如何不使用Java 8默认方法

如果您用谷歌搜索,您会发现Java 8中的默认方法带来了迦南语,多重继承是可用的。

与真正了解Java的专业人士在stackoverflow上进行了很好的讨论:

Java一直具有类型的多重继承。 默认方法增加了行为的多重继承,但没有状态的多重继承。 (大多数麻烦源于C ++等语言中状态的多重继承。)– Brian Goetz 2014年 6月21日,2:05

在本文中,我将研究如何解释和理解该声明。

继承类型

Brian Goetz的话中提到:

  • 类型的继承
  • 行为的继承,以及
  • 国家的继承。

类型的继承非常容易,并且对于Java程序员是众所周知的。 您可以在接口中定义抽象方法,但不指定抽象方法的工作方式,而仅指定方法的返回值和签名。 Java 8使用默认方法引入了行为继承而不是状态继承。 但是,您是否真的可以拥有行为继承而不拥有状态继承呢? 并不是的。 至少在Java 8中,您可以继承状态,尽管不建议这样做,它的执行效果不佳(我的意思是:它可能很慢),而且程序繁琐且容易出错。 但是可以,我将在这里展示如何操作。 (除了我在上面提到的文章中发布的线程本地废话之外。)

我相信Java 8发明者希望使用默认方法在标准运行时实现功能接口(例如流)时保持向后兼容性。 最近,我观看了Fargo系列,我觉得语言设计师对问题“是您真正想要的吗?”的回答是“是”。

使用默认方法进行状态继承

默认方法无法访问字段(静态字段除外,静态字段无论如何在接口中都是最终的,因此让我们暂时忘记它们)。 就像您无法从扩展了A的B类访问A类的私有字段一样。反之亦然:您无法从A访问B的私有字段。但是,您可以在B中拥有getter和setter,如果您声明了它们作为A中的抽象方法,您可以获得访问权限。 芝麻开门。 Getter和Setters是解决方案。

在接口中为要从默认方法访问的所有状态字段声明抽象方法时,可以访问它们。 这样,您将获得与真实状态继承相同的结果。 区别在于语法:您使用getter和setter方法而不是字段名称,并且必须在接口中声明这些方法。 通过这种方式,编译阶段会检查getter和setter是否确实存在。

您会看到Java 8的情况变得非常复杂。 将其与泛型混合使用,您可能找不到一个了解这一切的鲜活灵魂。 有一个结构,像

Outer.this.toString()

上面的示例代码中的代码可能会使它变得更加复杂,而没有实际的杠杆作用。

我相信我对Java 8中的默认方法以及如何使用它们有一定的了解。 但是,拥有10年Java和30年以上编程经验的经验不足以让我知道应该如何使用默认方法。 对于仍在生产代码中使用Java 1.6或更早版本的开发人员,我感到嫉妒:他们不必担心默认方法。 (这只是个玩笑。)

即使我尝试提供一些建议。

建议

切勿在默认方法中模仿状态继承。 虽然很难说出它在实践中是什么。 调用getter或setter显然是。 调用在实现类中实现的某些抽象方法可能会也可能不会。 如有疑问:最好不要。

永远不要使用我在另一篇文章中写的threadlocal技巧。

对于Java语言发明者使用的默认方法,使用默认方法:在库接口中保持向后兼容性。 如果您曾经发布过一个库并且它包含一个接口(否则,顺便说一句), 请不要对其进行更改...请考虑使用实现该接口的库来考虑客户端代码。 在Java 8中,您可以完成以下句子: 不要将其更改为不兼容的。 如果有一个新方法:创建一个默认实现,这样已经实现了先前版本的代码将保持兼容,并且无需扩展这些类。

翻译自: https://www.javacodegeeks.com/2015/02/default-methods-multiple-inheritance.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值