C++继承与组合

转自https://blog.csdn.net/caoyan_12727/article/details/52337297

  类的组合和继承一样,是软件重用的重要方式。组合和继承都是有效地利用已有类的资源。但二者的概念和用法不同。通过继承建立了派生类与基类的关系,它是一种 “是(is a)”的关系,如“白猫是猫”,“黑人是人”,派生类是基类的具体化实现,是基类中的一 种。通过组合建立了成员类与组合类(或称复合类)的关系,换句话说就是"有(has a)的关系".在功能上来看,它们都是实现系统功能重用,代码复用的最常用的有效的设计技巧,都是在设计模式中的基础结构。相信大家已了解的,类继承允许我们根据自己的实现来覆盖重写父类的实现细节,父类的实现对于子类是可见的,所以我们一般称之为白盒复用。对象持有(其实就是组合)要求建立一个号的接口,但是整体类和部分类之间不会去关心各自的实现细节,即它们之间的实现细节是不可见的,故成为黑盒复用。继承是在编译时刻静态定义的,即是静态复用,在编译后子类和父类的关系就已经确定了。而组合这是运用于复杂的设计,它们之间的关系是在运行时候才确定的,即在对对象没有创建运行前,整体类是不会知道自己将持有特定接口下的那个实现类。在扩展方面组合比集成更具有广泛性。继承中父类定义了子类的部分实现,而子类中又会重写这些实现,修改父类的实现,设计模式中认为这是一种破坏了父类的封装性的表现。这个结构导致结果是父类实现的任何变化,必然导致子类的改变。然而组合这不会出现这种现象。对象的组合还有一个优点就是有助于保持每个类被封装,并被集中在单个任务上(类设计的单一原则)。这样类的层次结构不会扩大,一般不会出现不可控的庞然大类。而类的继承就可能出来这些问题,所以一般编码规范都要求类的层次结构不要超过3层。组合是大型系统软件实现即插即用时的首选方式。最后还说一句,“优先使用对象组合,而不是继承”是面向对象设计的第二原则。在OOP中,组合和继承是扩展对象功能的两大利器,GoF在《设计模式》中指出OO设计的一大原则就是:优先使用对象组合,而不是类继承。但并不是说什么都设计都用组合,只是优先考虑组合,更不是说继承即使不好的设计,应该用组合,应为他们之间也有各自的优势。下面是他们之间的优缺点比比较表:

原文:https://blog.csdn.net/ocean181/article/details/6117369

 

关联

关联(association)表明某个对象可以向另一个对象通过某种方式发送消息。发送消息的方法可以通过指针成员变量, 也可以是方法参数、局部变量等等。例如:

class A
{
    private:
    B* itsB;
};


聚合

聚合(aggregation)是一种特殊的联系,它表明了“部分”到“整体”的关系,显著的特点就是不能包含循环的联系 (就是说,部分中不能包含整体)。如:

class Node
{
    private:
    vector<Node*> itsNodes;
};

上述代码只有当子节点不会成为父节点的父节点时(即,必须是树结构,不能是图结构),才能称之为聚合。

从实现的角度讲,聚合可以表示为:

class A {...} class B { A* a; .....}


组合

组合(composition)跟聚合几乎相同,唯一的区别就是“部分”不能脱离“整体”单独存在,就是说, “部分”的生命期不能比“整体”还要长。例如:

class Car
{
public:
    virtual ~Car() {delete itsCarb;}
private:
    Carburetor* itsCarb
};

从实现的角度讲,组合实现的形式是:

class A{...} class B{ A a; ...}

 

posted @ 2019-06-06 14:26  AKUNFYK  阅读(507)  评论(0编辑  收藏  举报