博客
关于我
复合优于继承
阅读量:565 次
发布时间:2019-03-09

本文共 1705 字,大约阅读时间需要 5 分钟。

当通过子类继承父类并不是代码重用的最佳方式时,存在一个显著的问题:它打破了对象封装性。具体来说,当父类的实现细节发生变化时,如果子类直接继承自父类,子类也会随之受到影响。这意味着只要父类的方法被修改,子类都会相应改变,这使得子类对父类产生了强耦合。

以HashSet类为例,假设我们创建了一个TestHashSet类,直接继承自HashSet。为了统计插入的元素数量,我们在TestHashSet中重写了add()和addAll()方法,并引入了一个计数器。然而,我们发现当调用addAll()方法时,实际上内部会调用super的add()方法。这样一来,每次将元素添加到集合中,计数器会被增加两次,最终导致计数值翻倍。

这样的继承方式引入了“自用性”问题(intrinsic call),因为它使得子类方法内部直接调用了父类的方法。为了解决这一问题,我们可以采用复合和转发的方式,而不是直接继承。

复合和转发的方式意味着我们不再直接扩展现有的类,而是创建一个新的包装类,它包含现有的类实例,并通过转发方法公开新的功能。这样的设计不仅将信赖移到了执行环境中,使现有类的实现细节可以在不影响其他类的情况下进行修改,同时也提高了系统的健壮性。

以下是一个利用复合和转发设计原则改造后的类示例:

// 使用包装类代替直接继承public class InstrumentedSet implements Set
{ private final ForwardingSet
wrapped; private int addCount = 0; public InstrumentedSet(E[] elements) { wrapped = new ForwardingSet<>(elements); } // 转发方法调用wrapped对象的实现 @Override public boolean add(E e) { addCount++; return wrapped.add(e); } @Override public boolean addAll(Collection
c) { addCount += c.size(); return wrapped.addAll(c); } // 提供统计方法 public int getAddCount() { return addCount; }}// 转发类实现了Set接口,内部包含目标集合对象public class ForwardingSet
implements Set
{ private final Set
target; public ForwardingSet(E[] elements) { target = new HashSet
(Arrays.asList(elements)); } @Override public boolean add(E e) { return target.add(e); } // 转发其他方法调用 // ...}

通过这种方式,我们避免了直接继承HashSet,简化了包装类的设计,并确保了统计逻辑的准确性。

总结来说,继承并不是解决所有问题的最佳方式。只有当子类确实是父类的子类型时,才应该使用继承。为了避免因继承带来的问题,我们可以采用复合和转发的机制。这种方法不仅提高了系统的可维护性,也让我们的设计更灵活,同时最大限度地遵守了封装原则。

封装性是软件设计中的核心原则之一,它意味着每个类只应该处理自己的事务。如果我们通过继承直接耦合一个类的实现细节,就违反了封装性。而通过包装类,我们可以将复杂的逻辑隐藏起来,使其更加容易管理和扩展。

转载地址:http://ovepz.baihongyu.com/

你可能感兴趣的文章
python基于flask搭建http服务(四)—— Docker容器化部署
查看>>
Python块键盘/鼠标输入
查看>>
python在使用HTMLTestRunner时,报告为空,错误提示<_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf_8'>...
查看>>
python在gpu上运行_【python】python开启GPU加速
查看>>
Python在def函数中使用for循环
查看>>
Python在def函数中使用for循环
查看>>
Python在Conda环境中,但在Windows虚拟环境中没有激活
查看>>
python系列【仅供参考】:python pip 错误 ModuleNotFoundError: No module named pip._internal 解决办法
查看>>
python图像条状状噪声,使用PYTHON PIL从验证码图像中删除背景嘈杂的线条
查看>>
Python图像处理:从内存加载jpeg
查看>>
python固定后缀(名物化词汇)词频统计:抽取+统计+可视化
查看>>
python商品评论数据采集与分析可视化系统 Flask框架 requests爬虫 NLP情感分析 毕业设计 源码
查看>>
python商品数据分析可视化系统(带爬虫)京东销售数据分析 计算机毕业设计 源码下载
查看>>
python商品库存管理系统 django框架 商品网站 MySQL数据库 源码下载 计算机毕业设计
查看>>
Python哪个版本最稳定好用2023.10.19
查看>>
Python和黑客技术的渊源
查看>>
Python和RF编写接口自动化
查看>>
python和js哪个难_【Python】记一次学习,Python 与 js 在实现闭包时的差异
查看>>
python和java哪个更值得学——来自知乎高赞回答
查看>>
python和c混合编程 github_在pycharm中使用git版本管理以及同步github的方法
查看>>