慎用继承

添加链接描述

之前看到Jake Wharton利用error prone搞了个java代码编译时检查工具,规则如下:除了使用final,abstract修饰的类外,所有类必须打上@Open注解。 言外之意不是专门被设计用来继承的类尽量用final修饰。无独有偶,kotlin中类默认是final的,想被继承需要手动加上open关键字。这都说明:这些大佬不希望类是默认可被继承的,也就是撸码过程中继承关系需要慎用。那么为什么呢?

继承打破了封装性

类A继承类B,B中一些方法的实现可能随不同版本变化而变化,有些变化可能会打破A的鲁棒性。例如我们想继承HashSet实现一个能统计历史加过多少个元素的hashSet,我们可能会重写其addAll和add方法,add的时候计数+1,同时调用父类HashSet的add方法,addAll(Collection<? extends E> c)的时候计数加上c.size(),同时调用父类HashSet的addAll方法。乍一看没什么问题。但是HashSet的addAll方法是通过add方法实现的,这就会导致调用add的时候计数正确,调用addAll的时候计数增加的不是c.size()而是两倍的c.size()。如果我们不了解addAll的实现细节,我们不容易注意到这个问题。那你可能会说那我不覆写addAll方法不就能work了吗?确实是,但是work的前提是HashSet的addAll方法一直通过add来实现。而这种实现细节没人能承诺一成不变。一旦子类的鲁棒性依赖于父类方法的实现细节这个继承关系就不太可靠,也不利于维护。而理想的封装正在于让调用方不需要关心方法实现的细节,只需要关注方法的结果。所以说这打破了封装性。实际上这种情况组合优于继承。利用包装类持有HashSet的对象来实现HashSet对应功能,同时包装类中维护一个计数,这样就不依赖于HashSet的实现细节来。一定是在两个类之间具备强烈的”is-a”关系的时候才去使用继承,Java中stack继承自vector,也是一种继承滥用。只有确认每个B都是A,才应该让B继承自A。否则考虑组合是不是更好?

要么不继承,要么就好好设计并提供文档说明

  • 被继承的类应该有文档说明其overridable方法的自用性(即调用了哪些可被覆写的方法) 虽然说好的API文档应该描述这个方法做了什么,而不用关心它具体怎么做到的。但是因为继承打破了封装性,所以我们实现继承的时候必须把overridable方法的自用性描述清楚。否则可能就是在挖坑。
  • 被设计继承的类必须提供适当的hook来让设计的protected方法进入内部工作流程 这条无需赘述,都看得懂。
  • 父类的constructor不能调用可被覆写的方法 原因很简单,父类constructor先于子类constructor执行,一旦调用可覆写的方法,子类中的变量实例很可能还没初始化,造成程序异常。同理 clone和readObject都不能调用可被覆写的方法 因为覆写的方法调用时间在反序列化和clone完成之前。
  • 尽量用接口代替抽象类。

总结来说就是,因为Java语言默认类可继承,一定程度上会加剧在工程中随意继承的现象,而随意继承会不经意间给后面维护埋下坑。并不说不要继承,而是一旦继承就好好设计并写好注释或者文档。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值