写在前面

学习面向对象编程语言,不能避免的会需要掌握委托和继承的概念,然而二者对初学者来说很难区分,本文就笔者的理解,谈谈二者的主要区别。

为避免引起混淆,本文使用了“委托类”和“被委托类”的概念,笔者通读后发现有些啰嗦,在此说明。

被委托类,工厂
方法,榨汁
委托类,水果

定义

首先明确,这两种模式提出的初衷都是为了提高代码的可复用性,而在具体实现上有所不同。

  • 委托:一个对象需要另一个对象的功能,于是捕获该对象,并发送到另一对象中进行功能调用。
  • 继承:获得一个基类的元素和方法。

举个例子:水果需要工厂进行榨汁,而水果本身不具有榨汁的功能,将榨汁的行为写给水果也不合适,于是我们把水果交给工厂(类)中的方法进行处理,这是委托(delegation)。
水果具有下落(fall)的行为,苹果也有下落的行为,在水果(类)中写“下落”这种行为,然后在苹果(类)中通过extends获得这个方法的复用,这是继承(inheritance)。

委托的几种形式

有了上面的基础,我们在进一步探讨委托在具体实现中的几种形式,以及它们的区别。
委托可以根据委托类和被委托类的关系粗略分为三类。

  • Use a (两个有委托的对象间没有从属关系)
  • Own a (委托方的存在完全依赖于被委托方,行为也由被委托方指定)
  • has a(被委托方存有委托方的一个实例,可以调用对方的一部分功能)

可能有些难区分own和has的差异,own倾向于A is a part of B这种关系,has则特指 B has a A in B这种关系,现在不理解也没关系,我们来看实例。

Dependency(依赖):短期的delegation。

  • 在这样的关系中,被委托类执行方法时通过参数的形式收到委托类的实例(副本),对其进行操作。
  • 两个类之间存在的关系为use-a.

我们沿袭上文,使用水果和工厂的关系来说明。

public class fruit{}//水果类
public class factory{public void juice(fruit a){println("a juiced");}//榨汁
}//工厂类

水果与工厂为一个简单的Dependency关系。

Association(关联):长期的delegation。

  • 在这样的关系中,被委托类首先明确委托类的身份,并允许被委托类使用委托类的身份做其它事(一般来说,被委托类不能做而委托类能做)。
  • 两个类之间存在的关系为has-a。
    我们引入果农来说明这一关系。
public class fruit{}//水果类
public class farmer{public fruit pick(){};//摘水果。public fruit trans(){};//运水果。
}
public class factory{private farmer.public void setFarmer(farmer toSet){this.farmer = toSet;}public void juice(fruit a){println("a juiced");}public void juice(farmer a){this.juice(a.trans());}//新的榨汁方法
}//工厂类

果农与工厂的关系为Association的简单实例,实际上,在应用中,这种合作关系的持续时间取决于双方的协定,并可以随时取消,因此,“长期”也不一定那么长,同时,在应用中,(委托关系)双方都应存有“合作伙伴”的列表,被“合作伙伴”调用时,一般需要验证合作伙伴身份的合法性,出于简单考虑,笔者仅介绍概念。

另:association多指双方互相调用。

Composition(组合):将委托类完全内部化的delegation。

  • 在这样的关系中,委托类的实例化,功能,生命周期均取决于被委托类的指派,委托类作为被委托类的一个private属性,且没有向外部提供更改该属性的方法(一般使用new 方法实例化之后便不再对其进行操作)。
  • 两个类之间存在的关系为a-part-of.

我们引入工厂里的榨汁机来说明这一关系。

public class fruit{}//水果类
public class liquidiser{public void juice(fruit a){println("a is juiced");}
}//榨汁机类
public class factory{private liquidiser inner;factory(){this.inner = new liquidiser();}public void juice(fruit a){inner.juice(a);}
}
}//工厂类

可见,榨汁机是工厂完全内部化的元素,它的生命周期和工厂一样,且行为为工厂行为的细化,这是一个composition的简单示例,脱离了工厂,榨汁机将不具有存在的意义

Aggregation(聚集):将委托类作为内部属性的delegation。

  • 在这样的关系中,委托类也为被委托类的内部属性,但是脱离了被委托类的使用(比如将被委托类释放),此时委托类仍然存在,并具有部分意义。
  • 两个类之间的关系为has-a。

我们引入从其它工厂借来的榨汁机来说明。


public class liquidiser{}//榨汁机类
public class factory{private List<liquidiser> innerList;public void lendLiquidiser(liquidiser input){this.innerList.add(input);}//借榨汁机。
}
}//工厂类

不难看出,此时的榨汁机虽然可以被工厂使用,但该榨汁机的属性并非由工厂决定的,如果工厂倒闭(工厂对象被释放),借来的榨汁机会得到继续的保留(如果没有刻意释放的话),这就是简单的Aggregation。

总结

我们看出,委托从弱到强有各自的优缺点,读者大可联想一下他们各自的应用领域。看懂了上文,我们用几张图来总结一下它们的层级关系,在java中,对象的生命周期处理比较智能,而在c++,c#等语言中,这些细微的差异会体现在析构函数(c++),委托类(c#)上。

委托和继承(Delegation and Inheritance)相关推荐

  1. Java中的委托和继承(Delegation and Inheritance)

    写在前面 概念 Delegation(委托) 委派的几种类型归纳 Dependency(依赖): 临时性的delegation Association(关联): 永久性的delegation Comp ...

  2. 重构类关系-Replace Inheritance with Delegation以委托取代继承十一

    重构类关系-Replace Inheritance with Delegation以委托取代继承十一 1.以委托取代继承 1.1.使用场景 某个子类只使用超类接口中的一部分,或是根本不需要继承而来的数 ...

  3. Replace Delegation with Inheritance(以继承取代委托)

    两个类之间使用委托关系,并经常为整个接口编写许多极简单的委托函数 重构:让委托类继承受托类

  4. C++_复合、委托、继承

    C++_复合.委托.继承 1.复合(has-a) )] 2.委托 3.继承(is-a) 3.1虚函数 基类析构函数一定要写成虚函数 目前见过的编译器的结果 析构相反 4.委托相关设计 参考:<C ...

  5. Javascript 原型和继承(Prototypes and Inheritance)

    Javascript 原型和继承(Prototypes and Inheritance) 收藏  前面我们看到了如何使用 constructor 来初始化对象.如果这样做,那么每一个创建的新对象都会对 ...

  6. 2022年5月22日【Jiawei_Z】C# 基础教程---刘铁锰 02 委托 事件 继承

    C# 基础教程-刘铁锰 02 委托 事件 继承 多态 重写. 类–什么是类? P25 23节 - 是一种数据结构 - 是一种数据类型 - 代表世界中的"种类" namespace ...

  7. 用委托机制(delegation)来定制行为

    用委托机制(delegation)来定制行为 应用程序的委托是Cocoa最重要的设计模式--委托机制的一个例子. 委托机制的想法在于:一个对象能有单一的委托对象,可以在某些事件发生的时候调用它.从委托 ...

  8. Replace Inheritance with Delegation(以委托取代继承)

    某个子类只使用超类接口中的一部分,或是根本不需要继承而来的数据 重构:在子类中新建一个字段用来保存超类,调整子类函数,令它改而委托超类,然后去掉两者的继承关系

  9. c++面向对象高级编程 学习五 组合、委托与继承

    组合 composition 表示has a queue类中有一个deque容器,这种关系叫做 组合 queue中的六个函数都是调用c的函数完成的 template <class T> c ...

最新文章

  1. 剑指offer:面试题12. 矩阵中的路径
  2. Datagridview中数字格式列 不显示小数点前面的0
  3. 周志华、宋继强谈如何培养高端AI人才,以及深度学习的局限性和未来
  4. Hadoop控制输出文件命名
  5. controller调用另一个controller中的方法 获取返回值_必须掌握!你知道 Spring 中运用的 9 种设计模式吗 ?...
  6. java驱动pl sql优点_用PL/SQL和Java开发Oracle8i应用程序
  7. python图像几何变换_Python 图像处理 OpenCV (5):图像的几何变换
  8. Android 功耗(10)---电流波形图(power monitor)
  9. get方法报空指针_C++基础教程之指针拷贝详解
  10. biztalk中架构验证、实例生成和验证
  11. 对广州链家网二手房数据进行分析
  12. kali免杀工具shellter
  13. 愿守内心宁静,砥砺此生修行
  14. 赴日工作之在留换签证
  15. 人类创造的工具是不是人工智能?
  16. python中类的self到底是什么
  17. (转)使用自定义行为扩展 WCF
  18. 规划 程序员的35岁危机
  19. tp5获取sql_tp5 sql语句 tp5 获取sql语句
  20. arm linux gcc 说明书,第七篇:gcc和arm-linux-gcc常用选项

热门文章

  1. 超右脑学习~那个小日本滴~
  2. 茶杯狐影视跳转Python源码
  3. Android基于极光推送实现单点登录
  4. 《洛杉矶时报》:失去李开复的Google,中国之路更艰难(9月23日)
  5. 毕业五年java研发求职经历
  6. PHP常用知识点汇总
  7. 掌控板ESP32与手机蓝牙通信mind+ appinventor图形编程
  8. 有奖补!2022年武汉市集成电路产品发展若干政策专项资金申报要求以及申报奖励补贴标准
  9. 天池-阿里巴巴全球调度大赛总结
  10. android租房软件代码,这几天网上很火的,程序员租房贴出代码