zoukankan      html  css  js  c++  java
  • 第1章 UML基础:类的关系

    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导航...
    ");
    }
    View Code

    //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匹马力的发动机发动了!
    ",mCapacity, mPower);
    }
    
    
    void CEngine::stop(){
        printf("发动机关闭了!
    ");
    }
    
    int CEngine::getCapacity()
    {
        return mCapacity;
    }
    
    void CEngine::setCapacity(int capacity)
    {
        mCapacity = capacity;
    }
    
    int CEngine::getPower()
    {
        return mPower;
    }
    
    void CEngine::setPower(int power)
    {
        mPower = power;
    }
    View Code

    //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)
    ", mNo + 1, 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;
    }
    View Code

    //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("正在减速...
    ");
    }
    
    
    void CVehicle::speedUp(){
        printf("正在加速...
    ");
    }
    
    
    void CVehicle::start(){
        printf("车子开始启动
    ");
    }
    
    
    void CVehicle::stop(){
        printf("车子停下
    ");
    }
    View Code

    //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 = 20;
    
        printf("%s%s自行车,最高时速:%d
    ", mColor, mMake, mTopSpeed);
    
        for (int i = 0; i < 2; i++)
        {
            CWheel cw(21, "B型自行车车轮", i);
            mWheels.push_back(cw); //会复制一份cw过去
        }
    
    }
    
    CBicycle::~CBicycle(){
        mWheels.clear();
    }
    
    
    void CBicycle::ride(){
        start();
        speedUp();
        printf("自行车行驶中...
    ");
        slowDown();
        stop();
    }
    View Code

    //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(0, 0)
    {
        mTopSpeed = topSpeed;
        mEngine.setCapacity(mTopSpeed + 1000);
        mEngine.setPower(mTopSpeed - 70);
        mColor = color;
        mMake = make;
        mGPSReceiver = gps;
    
        printf("%s%s车,最高时速:%d
    ", mColor, mMake, mTopSpeed);
    
        //生成4个轮子
        for (int i = 0; i < 4; i++)
        {
            CWheel cw(36, "A型汽车车轮", i);
            mWheels.push_back(cw); //会复制一份cw过去
        }
    }
    
    
    CCar::~CCar(){
        mWheels.clear();
    }
    
    
    void CCar::drive(){
        if (mGPSReceiver)
            mGPSReceiver->Navigate();
    
        mEngine.start();
    
        speedUp();
        printf("汽车行驶中...
    ");
        slowDown();
    
        mEngine.stop();
        stop();
    }
    View Code

    //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();
    }
    View Code

    //main.cpp

    #include <stdio.h>
    #include "CPerson.h"
    
    int main()
    {
        CPerson person;
    
        //GPS
        CGPSReceiver gps;
    
        //开车
        CCar* car = new CCar(&gps, "黑色", "红旗", 200);
        person.drive(car);
        delete car;
    
        printf("
    ");
    
        //骑自行车
        CBicycle *bicycle = new CBicycle();
        person.ride(bicycle);
        delete bicycle;
    
        printf("
    ");
    
        //测试GPS
        person.use(&gps);
    
        return 0;
    }
    
    /*输出结果:
    
    黑色红旗车,最高时速: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导航...
    */
  • 相关阅读:
    我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻。
    VGA显示器如何连接HDMI接口主机
    h5ai搭建自己的文件分享程序
    阿里钉钉智能硬件产品上线企业0元购买
    chevereto搭建自己的图床站点
    简单配置webpack自动刷新浏览器
    简易nodejs爬虫抓取博客园指定用户的文章及浏览量
    使用es6的set和map实现数组去重复
    promise实例小球运动
    ImportError: Couldn't import Django.
  • 原文地址:https://www.cnblogs.com/5iedu/p/5465247.html
Copyright © 2011-2022 走看看