本文转载自:
http://blog.csdn.net/kkforwork/article/details/46225747
一、继承、组合和聚合
继承和组合是两个完全不同的概念
继承,表达的是“is-a”的关系,两者之间是一种上下级的关系,比如,我们说“human is a animal“(人是动物的一种,换句话说,动物是人的上级),要表达这种关系,就可以使用继承
calss animal
{};
class human : public animal // 继承
{};
而组合和聚合,则是表达两个平等对象之间整体和局部的关系,而因为这种关系的紧密性的不同,而又分为了组合和聚合。组合表达的是“contain-a”的关系,整体和局部拥有相同的生命周期,换句话说,如果整体对象不存在了,那么局部对象也会消亡。在C++中,我们通常在整体类中加入一个局部类的对象作为其成员,来表达这种组合关系(整体对象创建的同时,也会创建局部对象,而整体对象消失了,局部对象也会消失),比如,我们说“human conains a head”(人有一个脑袋,人活着,脑袋也活着,如果人死了,脑袋也就是了),
class head
{};
calss human
{
private:
head h; // 数据成员对象表示的组合关系
}
聚合同样表的是整体和局部的关系,但是这种关系要松散得多,它表达的是一种“has-a”的关系,整体和局部拥有各自的生命周期,两者可以单独存在,相互独立,并不像组合一样两者相互依存,但两者也可以聚合在一起,形成一个新的类型。比如,我们说“human has a computer”(人有一台电脑,电脑和人都是各自独立的,而两者聚合在一起,就成了“有电脑的人”),在C++中,我们通常在整体类中加入指向局部类的指针,来表达这种“聚合”关系(整体对象创建的时候,不一定有局部对象,可能已经创建,也可以还没有,而整体对象消失了,局部对象还可以继续存在,也可能消失,想象一下电脑和人的关系,生不带来,死不带去)。
calss computer
{};
class human
{
// ...
private:
computer* pCom; // 指针表示的聚合关系
};
总结起来,继承表达的是一种上下级的关系(is-a),聚合表达的是一种松散的整体和局部的关系(has-a),而组合表达的是一种紧密的整体局部关系(contain-a)
另外:
class A{
private:
B* p_b;
};
A::A(){
p_b=new B;
}
A::~A(){
delete p_b;
}
A与B的关系是组合。虽然是用指针表示的,依然是组合关系。
到底是组合还是聚合,其实现形式(用成员还是指针)不是判断标准,两者生命周期的差异,才是判断标准。两者生命周期相同的,是组合,比如成员变量,你这里用指针的实现,而生命周期不同的,才是聚合。
二、关联和聚合
关联和聚合的区别主要在语义上,关联的两个对象之间一般是平等的,例如你是我的朋友,聚合则一般不是平等的,例如一个公司包含了很多员工,其实现上是差不多的。
聚合和组合的区别则在语义和实现上都有差别,组合的两个对象之间其生命期有很大的关联,被组合的对象是在组合对象创建的同时或者创建之后创建,在组合对象销毁之前销毁。一般来说被组合对象不能脱离组合对象独立存在,而且也只能属于一个组合对象,例如一个文档的版本,必须依赖于文档的存在,也只能属于一个文档。聚合则不一样,被聚合的对象可以属于多个聚合对象,例如一个员工可能可以属于多个公司。