1. 类的关系

1.1 继承和实现:继承表示有父子关系

1.2 依赖:(use–a),表示一个类要使用(use)另一个类。

(1)类图

(2)三种依赖方式函数参数或返回值局部变量静态成员变量或函数

class C21
{
public: //1、使用形参或返回值发生依赖关系
C22 test(C22 theC22); //2、使用局部变量发生依赖关系
void test()
{
C22 theC22; //或C22* theC22 = new C22;
//离开这个作用域后the22要销毁
} //3、全局变量或静态变量(函数)发生依赖关系
void test()
{
C22 theC22 = g_C22; //g_C22为全局变量
C22::func(); //使用类的静态成员函数
}
};

1.3 关联:是一种平等的、朋友关系

(1)双向关联:双方都知道对方的存在,都可以调用对方的公有成员变量和函数

  ①在代码的表现为双方都拥有对方的一个指针或引用。注意,表现为拥有对方的一个 “指针” 和 “引用”。

  ②之所以是指针和引用是有原因的。如果是值(对象)那么就不是关联了,而是组合。因为是值的话,C31对象消失C32对象也会消失。这和组合的定义就一样了 :整体与部分的关系,而且整体消失部分也会消失,部分不能独立于整体存在。

(2)单向关联

  ①表示相识关系,指C33知道C34,可以调用C34的公共成员变量和函数

  ②代码上表示为C33有C34的指针,而C34对C33一无所知。

(3)自身关联:自己的内部有着一个指向自身的指针或引用

1.4 聚合与组合

(1)聚合:(has–a ),表示整体-部分的关系,但部分可以脱离整体而单独存在。

  ①如C41聚合C42,但是C42可以离开C41而独立存在。在创建C41类的对象时,一般不会马上创建theC42对象,而是等待一个外界的对象传给它。

  ②当用C++代码来描绘关联和聚合时都是一个类包含了另外一个类的指针。但是他们是有区别的,这个区别不是C++语法上的差别,而是语义上的差别聚合是整体和部分的关系,而且关联是平等的朋友关系,比如。张三和李四,是关联。而张三和张三的杯子是聚合。张三和张三的鼻子是组合。

(2)组合:Contains-a。表示整体-部分的关系,但部分不能脱离整体而单独存在。如手脚是身体的一部分,轮胎与汽车的一部分,脱离后就没有意义了。

  ①一般组合用的是值对象(如theC44,表示其生命期与整体一致)

  ②聚合是指针。但有时组合也可以用指针,在构造函数中创建对象,析构函数中销毁对象。但不同的是聚合,一般其对象指针是由类外传入的,而组合是在类内部的构造函数中new出来的

  ③从语义上看,组合与聚合也是不一样的。当表示聚合时,部分可以脱离整体。而组合不行。

2. 依赖和聚合/组合、关联的区别

  ①关联是类之间的一种平等关系,例如老师和学生,老公和老婆,水壶装水等就是一种关系。从语义上很容易区分出来

  ②组合是一种整体-部分的关系,在问题域中这种关系很明显,从语义上可以直接分析得出。例如轮胎是车的一部分,树叶是树的一部分,手脚是身体的一部分这种的关系,非常明显的整体-部分关系。

  ③上述的几种关系(依赖、关联、聚合/组合)在代码中可能以指针、引用、值等的方式在另一个类中出现,不拘于形式,只有配合语义,结合上下文来判断。而只给出一段代码让我们来判断是什么关系,还是无法准确判断的。

  ④这里还要说明一下,所谓的这些关系只是在某个问题域才有效,离开了这个问题域,可能这些关系就不成立了。

3. 类关系的实例分析

(1)类图

(2)代码实现

//CGPSReceiver.h

#ifndef _CGPSRECEIVER_H_
#define _CGPSRECEIVER_H_ class CGPSReceiver
{
public:
void Navigate();
}; #endif // _CGPSRECEIVER_H_

//CGPSReceiver.cpp

///////////////////////////////////////////////////////////
// CGPSReceiver.cpp
// Implementation of the Class CGPSReceiver
// Created on: 06-5月-2016 9:25:01
// Original author: SantaClaus
/////////////////////////////////////////////////////////// #include "CGPSReceiver.h"
#include <stdio.h> void CGPSReceiver::Navigate(){ printf("使用GPS导航...\n");
}

//CEngine.h

#if !defined(_CENGINE_H_)
#define _CENGINE_H_ class CEngine
{
public:
CEngine(int capacity, int power);
void start();
void stop(); int getCapacity();
void setCapacity(int capacity);
int getPower();
void setPower(int power); private:
int mCapacity;
int mPower; }; #endif //!_CENGINE_H_

//CEngine.cpp

///////////////////////////////////////////////////////////
// CEngine.cpp
// Implementation of the Class CEngine
// Created on: 06-5月-2016 9:25:01
// Original author: SantaClaus
/////////////////////////////////////////////////////////// #include "CEngine.h"
#include <stdio.h> CEngine::CEngine(int capacity, int power)
{
mCapacity = capacity;
mPower = power;
} void CEngine::start(){
printf("%d cc,%d匹马力的发动机发动了!\n",mCapacity, mPower);
} void CEngine::stop(){
printf("发动机关闭了!\n");
} int CEngine::getCapacity()
{
return mCapacity;
} void CEngine::setCapacity(int capacity)
{
mCapacity = capacity;
} int CEngine::getPower()
{
return mPower;
} void CEngine::setPower(int power)
{
mPower = power;
}

//CWheel.h

#if !defined(_CWHEEL_H_)
#define _CWHEEL_H_ class CWheel
{
public:
CWheel(int size, const char* typeName, int no); CWheel& operator = (const CWheel& cw);
CWheel(const CWheel& cw); //复制构造函数 protected:
int mNo;
int mSize;
const char* mTypeName; void check(); }; #endif // !defined(_CWHEEL_H_)

//CWheel.cpp

///////////////////////////////////////////////////////////
// CWheel.cpp
// Implementation of the Class CWheel
// Created on: 06-5月-2016 9:25:05
// Original author: SantaClaus
/////////////////////////////////////////////////////////// #include "CWheel.h"
#include <stdio.h> void CWheel::check(){
printf("检查第%d个车轮:型号(%s),大小(%d)\n", mNo + , mTypeName, mSize);
} CWheel::CWheel(int size, const char* name, int no){
mSize = size;
mNo = no;
mTypeName = name; check();
} CWheel& CWheel::operator = (const CWheel& cw)
{
mNo = cw.mNo;
mSize = cw.mSize;
mTypeName = cw.mTypeName;
return *this;
}
CWheel::CWheel(const CWheel& cw) //复制构造函数
{
mNo = cw.mNo;
mSize = cw.mSize;
mTypeName = cw.mTypeName;
}

//CVehicle.h

#if !defined(_CVEHICLE_H_)
#define _CVEHICLE_H_ #include "CWheel.h"
#include <list> using namespace std; class CVehicle
{
protected:
char* mColor;
char* mMake;
int mTopSpeed; list<CWheel> mWheels; //车轮与CVehicle是组合关系。声明为值对象 void slowDown();
void speedUp();
void start();
void stop(); }; #endif // !defined(_CVEHICLE_H_)

//CVehicle.cpp

#include "CVehicle.h"

void CVehicle::slowDown(){
printf("正在减速...\n");
} void CVehicle::speedUp(){
printf("正在加速...\n");
} void CVehicle::start(){
printf("车子开始启动\n");
} void CVehicle::stop(){
printf("车子停下\n");
}

//CBicycle.h

#if !defined(_CBICYCLE_H_)
#define _CBICYCLE_H_ #include "CVehicle.h" class CBicycle : public CVehicle
{
public:
CBicycle();
~CBicycle();
void ride(); }; #endif // !defined(_CBICYCLE_H_)

//CBicycle.cpp

///////////////////////////////////////////////////////////
// CBicycle.cpp
// Implementation of the Class CBicycle
// Created on: 06-5月-2016 9:25:01
// Original author: SantaClaus
/////////////////////////////////////////////////////////// #include "CBicycle.h" CBicycle::CBicycle():CVehicle(){
mColor = "白色";
mMake = "永久";
mTopSpeed = ; printf("%s%s自行车,最高时速:%d\n", mColor, mMake, mTopSpeed); for (int i = ; i < ; i++)
{
CWheel cw(, "B型自行车车轮", i);
mWheels.push_back(cw); //会复制一份cw过去
} } CBicycle::~CBicycle(){
mWheels.clear();
} void CBicycle::ride(){
start();
speedUp();
printf("自行车行驶中...\n");
slowDown();
stop();
}

//CCar.h

#if !defined(_CCAR_H_)
#define _CCAR_H_ #include "CEngine.h"
#include "CGPSReceiver.h"
#include "CVehicle.h" class CCar : public CVehicle
{
public:
CCar(CGPSReceiver* gps, char* color, char* make, int topSpeed);
~CCar();
void drive(); protected:
CEngine mEngine; //发动机与CCar类是组合关系,声明为值对象
CGPSReceiver *mGPSReceiver; //导航与CCar是聚合关系,声明为指针,由外部传入
}; #endif // !defined(_CCAR_H_)

//CCar.cpp

///////////////////////////////////////////////////////////
// CCar.cpp
// Implementation of the Class CCar
// Created on: 06-5月-2016 9:25:01
// Original author: SantaClaus
/////////////////////////////////////////////////////////// #include "CCar.h" CCar::CCar(CGPSReceiver* gps, char* color, char* make,int topSpeed) :mEngine(, )
{
mTopSpeed = topSpeed;
mEngine.setCapacity(mTopSpeed + );
mEngine.setPower(mTopSpeed - );
mColor = color;
mMake = make;
mGPSReceiver = gps; printf("%s%s车,最高时速:%d\n", mColor, mMake, mTopSpeed); //生成4个轮子
for (int i = ; i < ; i++)
{
CWheel cw(, "A型汽车车轮", i);
mWheels.push_back(cw); //会复制一份cw过去
}
} CCar::~CCar(){
mWheels.clear();
} void CCar::drive(){
if (mGPSReceiver)
mGPSReceiver->Navigate(); mEngine.start(); speedUp();
printf("汽车行驶中...\n");
slowDown(); mEngine.stop();
stop();
}

//CPerson.h

#if !defined(_CPERSON_H_)
#define _CPERSON_H_ #include "CGPSReceiver.h"
#include "CBicycle.h"
#include "CCar.h" class CPerson
{
public:
CGPSReceiver *mGPSReceiver; //CGPSReceiver与CPerosn是关联关系(平等、朋友关系),由类外传入 void drive(CCar* car); //CCar与CPerson通过形参发生依赖关系
void ride(CBicycle* bicle);//CBicycle与CPerson通过形参发生依赖关系
void use(CGPSReceiver* gps);//将gps传给mGPSReceiver;
}; #endif // !defined(_CPERSON_H_)

//CPerson.cpp

///////////////////////////////////////////////////////////
// CPerson.cpp
// Implementation of the Class CPerson
// Created on: 06-5月-2016 9:25:04
// Original author: SantaClaus
/////////////////////////////////////////////////////////// #include "CPerson.h" void CPerson::drive(CCar* car){
car->drive();
} void CPerson::ride(CBicycle* bicycle){
bicycle->ride();
} void CPerson::use(CGPSReceiver* gps){ mGPSReceiver = gps; mGPSReceiver->Navigate();
}

//main.cpp

#include <stdio.h>
#include "CPerson.h" int main()
{
CPerson person; //GPS
CGPSReceiver gps; //开车
CCar* car = new CCar(&gps, "黑色", "红旗", );
person.drive(car);
delete car; printf("\n"); //骑自行车
CBicycle *bicycle = new CBicycle();
person.ride(bicycle);
delete bicycle; printf("\n"); //测试GPS
person.use(&gps); return ;
} /*输出结果: 黑色红旗车,最高时速:200
检查第1个车轮:型号(A型汽车车轮),大小(36)
检查第2个车轮:型号(A型汽车车轮),大小(36)
检查第3个车轮:型号(A型汽车车轮),大小(36)
检查第4个车轮:型号(A型汽车车轮),大小(36)
使用GPS导航...
1200 cc,130匹马力的发动机发动了!
正在加速...
汽车行驶中...
正在减速...
发动机关闭了!
车子停下 白色永久自行车,最高时速:20
检查第1个车轮:型号(B型自行车车轮),大小(21)
检查第2个车轮:型号(B型自行车车轮),大小(21)
车子开始启动
正在加速...
自行车行驶中...
正在减速...
车子停下 使用GPS导航...
*/

第1章 UML基础:类的关系的更多相关文章

  1. UML的类图关系分为: 关联、聚合/组合、依赖、泛化(继承)

    UML的类图关系分为: 关联.聚合/组合.依赖.泛化(继承).而其中关联又分为双向关联.单向关联.自身关联:下面就让我们一起来看看这些关系究竟是什么,以及它们的区别在哪里. 1.关联 双向关联:C1- ...

  2. UML类图关系全面剖析

    UML的类图关系分为: 关联.聚合/组合.依赖.泛化(继承).而其中关联又分为双向关联.单向关联.自身关联:下面就让我们一起来看看这些关系究竟是什么,以及它们的区别在哪里. 1.关联 双向关联:C1- ...

  3. UML类图关系表示

    UML 之 C++类图关系全面剖析 分类: 软件设计与架构2008-10-16 08:52 5165人阅读 评论(3) 收藏 举报 umlc++borderclasscblog UML的类图关系分为: ...

  4. 设计模式基础:类及类关系的UML表示

    设计模式基础:类及类关系的UML表示 2009-10-26 17:00 by 宗哥, 1891 阅读, 1 评论, 收藏, 编辑 UML中,类关系分为这几种,泛化(generalization), 实 ...

  5. 设计模式之序章-UML类图那点事儿

    设计模式之序-UML类图那点事儿 序 打14年年底就像写那么一个系列,用于讲设计模式的,代码基于JAVA语言,最早接触设计模式是大一还是大二来着,那时候网上有人给推荐书,其中就有设计模式,当时给我推荐 ...

  6. UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)

    UML类图关系(泛化 .继承.实现.依赖.关联.聚合.组合) 继承.实现.依赖.关联.聚合.组合的联系与区别 分别介绍这几种关系: 继承 指的是一个类(称为子类.子接口)继承另外的一个类(称为父类.父 ...

  7. [UML]UML系列——类图class的泛化关系

    系列文章       [UML]UML系列——用例图Use Case       [UML]UML系列——用例图中的各种关系(include.extend)       [UML]UML系列——类图C ...

  8. 【转】UML类图与类的关系详解

    UML类图与类的关系详解   2011-04-21 来源:网络   在画类图的时候,理清类和类之间的关系是重点.类的关系有泛化(Generalization).实现(Realization).依赖(D ...

  9. UML类图与类的关系详解

    摘自:http://www.uml.org.cn/oobject/201104212.asp UML类图与类的关系详解 2011-04-21 来源:网络 在画类图的时候,理清类和类之间的关系是重点.类 ...

随机推荐

  1. mysql innodb表 utf8 gbk占用空间相同,毁三观

    昨天因为发生字符集转换相关错误,今天想验证下utf8和gbk中英文下各自空间的差距.这一测试,绝对毁三观,无论中文还是中文+英文,gbk和utf8占用的实际物理大小完全相同,根本不是理论上所述的“UT ...

  2. android.widget.RadioButton 单选按钮(转)

    大家好,我们今天这一节要介绍的是RadioGroup 的组事件.RadioGroup 可将各自不同的RadioButton ,设限于同一个Radio 按钮组,同一个RadioGroup 组里的按钮,只 ...

  3. C: const and static keywords

    原文:http://www.noxeos.com/2011/07/29/c-const-static-keywords/ C: const and static keywords Ok, once a ...

  4. 初学Node(五)文件I/O

    文件读写 Node的出现的一个亮点就是让JS也有了读写文件的能力,而且实现起来要比其他语言更简单,对文件的一些操作我们都可通过fs模块来完成.fs即fileSystem的缩写,fs模块可以完成对文件的 ...

  5. 【转】self.myOutlet=nil、viewDidUnload、dealloc的本质剖析

    对于iphone开发人员来说,内存管理是极为重要的技巧,哪怕程序的功能再强大,设计再漂亮,如果内存控制不好,也难逃程序莫名退出的噩运,这与网页开发是完全不同的. 内存控制里面有很多门道,在这里分析一下 ...

  6. iOS设计模式-单例模式

    (一)什么是单例模式(Singleton) 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点 *最初的定义是在<设计模式>(Addison-Wesley)中 解读 1> ...

  7. iOS 你将会遇到的

    1.解释ARC原理,ARC引入之后,iOS增加了几个修饰符,分别是什么?并解释何时应该使用? 2.给你一个可变数组aMutableArray,请写出你认为较好的算法代码. 3.UITableView是 ...

  8. JSPatch一些容易犯错的地方

    JSPatch一些自己使用后的发现: 1.JS不区分整数和浮点数.解析字典以后的value不需要通过 floatValue等方法转换,而是自动就转换成对应的数据类型. 2.nil在JSPatch中 不 ...

  9. socket服务器开发中的SO_REUSEADDR选项与让人心烦的TIME_WAIT

    1 发现问题 我在开发一个socket服务器程序并反复调试的时候,发现了一个让人无比心烦的情况:每次kill掉该服务器进程并重新启动的时候,都会出现bind错误:error:98,Address al ...

  10. maven问题-"resolution will not be reattempted until the update interval of MyRepo has elapsed"

    最近在家里写maven程序的时候老是出现问题,有些问题到了公司就突然消失了. 在修改pom文件后保存的反应还是比较明显的,家里的网遇到有些依赖根本下载不了..墙. 但是到了公司,不但速度快,几乎啥都能 ...