类与类之间的关系
关系的分类
从软件设计的角度来看,一群孤立的类无法构成一个完整的软件系统,类与类之间必然存在大量的联系与互动,类是实体的抽象,现实中复杂多样的实体连接,转换为关系是需要我们仔细的斟酌。
纵向的关系,横向的关系
类之间的关系在大体上分为两种,一种是纵向的,另一种是横向的。
一、纵向的就是继承,它是OO的三个特征之一。在UML中称作:
泛化(Generalization) :表示一个类对另一个类的继承。*
实现(Realization) : 实现指的是一个class类实现interface接口(可以是多个)的功能。*
二、横向关系较为微妙,按照UML的建议大体上可以分为四种:
依赖 (Dependency) :一个对象在运行期会使用到另一个对象的关系。
关联 (Association) : 某个对象会长期的持有另一个对象的引用。
聚合 (Aggregation) :聚合是强版本的关联。它暗含着一种所属关系以及生命期关系。。
组合 (Composition) : 整体与局部的关系,局部不可以脱落整体存在
它们的强弱关系是没有异议的:依赖 < 关联 < 聚合 < 组合
泛化关系(Generalization)
就是继承关系。
UML表示:A继承B
实现关系(Realization)
实现指的是一个class类实现interface接口(可以是多个)的功能,实现是类与接口之间最常见的关系。 C++中并没有为接口定义特殊的标识符,用特殊抽象类来表示接口,接口类应满足以下条件:
1、接口类中不应该声明成员变量,静态变量。
2、可以声明静态常量作为接口的返回值状态,需要在对应的cpp中定义并初始化,访问时需要使用"接口类型::静态常量名"访问
2、定义的接口方法使用virtual 修饰符 和 “=0” 修饰,表示该方法是纯虚的。
3、因为接口类是无法创建对象的,所以不应该编写构造函数和析构函数。
UML表示:
C++实现
class IShape
{
public:
virtual int area() = 0;
static const int MIN_AREA;
};
依赖关系(Dependency)
就像赌徒与色子的关系,赌徒使用色子,只是赌的时候用色子,其他时候并没有关系。依赖关系描述一个对象在运行期会使用到另一个对象的关系。与关联关系不同的是,依赖关系是一种临时性的关系,它通常都是在运行期产生。
UML表示:
C++实现
class CCar
{
// Do something
void run();
};
class CPerson
{
void MoveFast(CCar &pCar)
{
pcar.run();
}
};
关联关系(Dependency)
关联就是某个对象会长期的持有另一个对象的引用,而二者的关联往往也是相互的。关联的两个对象彼此间没有任何强制性的约束,只要二者同意,可以随时解除关系或是进行关联,它们在生命期问题上没有任何约定。被关联的对象还可以再被别的对象关联,所以关联是可以共享的。
例如:
UML表示:
C++实现
在C++中表示为,持有对象的指针
class CCar
{
// Do something
void run();
};
class CPerson
{
CCar *hisCar;
};
聚合关系(Aggregation)
聚合是强版本的关联。它暗含着一种所属关系以及生命期关系。被聚合的对象还可以再被别的对象关联,所以被聚合对象是可以共享的。虽然是共享的,聚合代表的是一种更亲密的关系。
聚合是整体与部分的关系,且部分可以离开整体而存在,如,车和轮胎是整体和部分的关系,轮胎离开车还可以存在。
是关联关系的一种特例,他体现的是整体与部分、拥有的关系,即has-a的关系,此时整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享;比如计算机与CPU、公司与员工的关系等;表现在代码层面,和关联关系是一致的,只能从语义级别来区分
UML表示:
C++实现
在C++中表示为,持有对象的指针
// Car.h
#include "Tyre.h"
class CCar
{
public:
vector<Tire> tires;
};
组合关系(Composition)
组合是关系当中的最强版本,它直接要求包含对象对被包含对象的拥有以及包含对象与被包含对象生命期的关系。被包含的对象还可以再被别的对象关联,所以被包含对象是可以共享的,然而绝不存在两个包含对象对同一个被包含对象的共享。
组合也是关联关系的一种特例,他体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合;他同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束;比如你和你的大脑;
UML表示:
C++实现
在C++中表示为,持有对象的指针
// Car.h
#include "Tyre.h"
class CPerson
{
public:
Heart heart;
};