委托和继承(Delegation and Inheritance)
写在前面
学习面向对象编程语言,不能避免的会需要掌握委托和继承的概念,然而二者对初学者来说很难区分,本文就笔者的理解,谈谈二者的主要区别。
为避免引起混淆,本文使用了“委托类”和“被委托类”的概念,笔者通读后发现有些啰嗦,在此说明。
定义
首先明确,这两种模式提出的初衷都是为了提高代码的可复用性,而在具体实现上有所不同。
- 委托:一个对象需要另一个对象的功能,于是捕获该对象,并发送到另一对象中进行功能调用。
- 继承:获得一个基类的元素和方法。
举个例子:水果需要工厂进行榨汁,而水果本身不具有榨汁的功能,将榨汁的行为写给水果也不合适,于是我们把水果交给工厂(类)中的方法进行处理,这是委托(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)相关推荐
- Java中的委托和继承(Delegation and Inheritance)
写在前面 概念 Delegation(委托) 委派的几种类型归纳 Dependency(依赖): 临时性的delegation Association(关联): 永久性的delegation Comp ...
- 重构类关系-Replace Inheritance with Delegation以委托取代继承十一
重构类关系-Replace Inheritance with Delegation以委托取代继承十一 1.以委托取代继承 1.1.使用场景 某个子类只使用超类接口中的一部分,或是根本不需要继承而来的数 ...
- Replace Delegation with Inheritance(以继承取代委托)
两个类之间使用委托关系,并经常为整个接口编写许多极简单的委托函数 重构:让委托类继承受托类
- C++_复合、委托、继承
C++_复合.委托.继承 1.复合(has-a) )] 2.委托 3.继承(is-a) 3.1虚函数 基类析构函数一定要写成虚函数 目前见过的编译器的结果 析构相反 4.委托相关设计 参考:<C ...
- Javascript 原型和继承(Prototypes and Inheritance)
Javascript 原型和继承(Prototypes and Inheritance) 收藏 前面我们看到了如何使用 constructor 来初始化对象.如果这样做,那么每一个创建的新对象都会对 ...
- 2022年5月22日【Jiawei_Z】C# 基础教程---刘铁锰 02 委托 事件 继承
C# 基础教程-刘铁锰 02 委托 事件 继承 多态 重写. 类–什么是类? P25 23节 - 是一种数据结构 - 是一种数据类型 - 代表世界中的"种类" namespace ...
- 用委托机制(delegation)来定制行为
用委托机制(delegation)来定制行为 应用程序的委托是Cocoa最重要的设计模式--委托机制的一个例子. 委托机制的想法在于:一个对象能有单一的委托对象,可以在某些事件发生的时候调用它.从委托 ...
- Replace Inheritance with Delegation(以委托取代继承)
某个子类只使用超类接口中的一部分,或是根本不需要继承而来的数据 重构:在子类中新建一个字段用来保存超类,调整子类函数,令它改而委托超类,然后去掉两者的继承关系
- c++面向对象高级编程 学习五 组合、委托与继承
组合 composition 表示has a queue类中有一个deque容器,这种关系叫做 组合 queue中的六个函数都是调用c的函数完成的 template <class T> c ...
最新文章
- 剑指offer:面试题12. 矩阵中的路径
- Datagridview中数字格式列 不显示小数点前面的0
- 周志华、宋继强谈如何培养高端AI人才,以及深度学习的局限性和未来
- Hadoop控制输出文件命名
- controller调用另一个controller中的方法 获取返回值_必须掌握!你知道 Spring 中运用的 9 种设计模式吗 ?...
- java驱动pl sql优点_用PL/SQL和Java开发Oracle8i应用程序
- python图像几何变换_Python 图像处理 OpenCV (5):图像的几何变换
- Android 功耗(10)---电流波形图(power monitor)
- get方法报空指针_C++基础教程之指针拷贝详解
- biztalk中架构验证、实例生成和验证
- 对广州链家网二手房数据进行分析
- kali免杀工具shellter
- 愿守内心宁静,砥砺此生修行
- 赴日工作之在留换签证
- 人类创造的工具是不是人工智能?
- python中类的self到底是什么
- (转)使用自定义行为扩展 WCF
- 规划 程序员的35岁危机
- tp5获取sql_tp5 sql语句 tp5 获取sql语句
- arm linux gcc 说明书,第七篇:gcc和arm-linux-gcc常用选项