首页 > 其他分享 >如何理解 少用继承,多用组合

如何理解 少用继承,多用组合

时间:2023-02-19 21:35:54浏览次数:36  
标签:多用 组合 继承 子类 接口 橡皮 鸭子

HeadFirst 设计模式一书中,开篇就提到了这个有趣的点:

 

 当我们想让鸭子能飞的时候,首先跳出来的想法是给鸭子类增加一个fly()方法,然后所有的子类直接继承完事;

结果,有一个橡皮鸭类也继承了,导致了我们不想看见橡皮鸭满天飞的后果;这里显然是有问题的,然后我们在想,橡皮鸭类中直接override这个方法,实现为空不就行了吗;看着是解决了问题,但是,如果后面不断有新的类来继承鸭子类,为每个新增的类我们都要检查fly() 方法,quack()方法等;或者当想要新增特性时,要检查每个子类的对应行为是否需要override掉;

一个进阶的想法是:

 

 这样的话,每个类显式的声明自己是否继承Flyable接口,或者Quackable接口,来保证自己的行为不会偏离预期;但是其实,为了解决一小部分的问题,带来了更多的重复代码。

推荐的做法是:

 

 这么做的好处是,鸭子的行为不再是继承而来的,而是组合实现的;组合的优势在于,可以在运行时动态地改变行为;

继承的问题在于,我们过于依赖实现,也就是父类有这个方法的实现,我们只能选择默认,或者覆盖;

不符合一条重要的设计原则:针对接口编程,而不是针对实现编程;

 

标签:多用,组合,继承,子类,接口,橡皮,鸭子
From: https://www.cnblogs.com/Arnold-Zhang/p/17135637.html

相关文章

  • python中的类继承
    """"""classAnimal(object):def__init__(self,name,food):self.name=nameself.food=foodself.blood=100self.waise......
  • m基于多用户MIMO系统的分布式可重构注水算法的matlab仿真
    1.算法描述       在单用户MIMO场景中,空间复用技术能够带来高数据速率的传输,但是也需要一些前提条件,比如发射端的预编码或者接收端的信道估计与信号检测。然而,在大......
  • m基于多用户MIMO系统的分布式可重构注水算法的matlab仿真
    1.算法描述在单用户MIMO场景中,空间复用技术能够带来高数据速率的传输,但是也需要一些前提条件,比如发射端的预编码或者接收端的信道估计与信号检测。然而,在大多数的通信系统......
  • 组合数学 2
    可重集合排列\(n\)种字母,每种字母\(a_i\)个,有多少种不同的排列?\[C_{\suma_{1\simn}}^{a_{1}}\cdotC_{\suma_{2\simn}}^{a_{2}}\cdot\ldots\cdotC_{a_n}^{a_{......
  • 组合数学 1
    备忘用。排列组合\[\begin{aligned}A_{n}^{m}=n\left(n-1\right)\cdot\left(n-2\right)\cdot\ldots\cdot\left(n-m+1\right)=\dfrac{n!}{\left(n-m\right)!......
  • 排列组合的知识
    排列组合公式 排列组合方法一、计数按照统计要求,将符合所有条件的结果筛选出来,统计所有结果的数量叫做计数!二、分类加法完成一件事的方法,有n类方案,第一类方案中有......
  • 多继承与虚继承
    多继承与虚继承多继承的语法:class派生类名:[继承方式1]基类名1,[继承方式2]基类名2,......{派生类新增加的成员};虚继承可以解决菱形继承的二义性和数据......
  • 继承的对象模型
    继承的对象模型1)创建派生类对象时,先调用基类的构造函数,再调用派生类的构造函数。2)销毁派生类对象时,先调用派生类的析构函数,再调用基类的析构函数。如果手工调用派生类的......
  • 为什么子进程要继承处理器亲缘性?
    请先考虑一个典型的程序为什么需要启动一个子进程。(当然资源管理器不算一个典型的程序)这是因为手头的任务被分解为子任务,无论出于何种原因,这些子任务都被放入子流程中。......
  • 【视频】风险价值VaR原理与Python蒙特卡罗Monte Carlo模拟计算投资组合实例|附代码数
    原文链接:http://tecdat.cn/?p=22862 最近我们被客户要求撰写关于风险价值VaR的研究报告,包括一些图形和统计输出。风险价值(VaR)是一种统计数据,用于量化公司、投资组......