在UML類圖中,類與類之間有幾種常見關(guān)系:依賴、關(guān)聯(lián)、聚合、組合、泛化。
1、依賴(Dependency)
依賴是一種很有用的關(guān)系,它用來表述一個類A“use”了另一個類B。A可以是通過任何方式“use”類B,如:
1)A的成員函數(shù)的返回值為B;
2)A的成員函數(shù)使用B作為函數(shù)參數(shù);
3)A的成員函數(shù)的內(nèi)部實(shí)現(xiàn)使用了B;
依賴關(guān)系通常使用虛線箭頭“---->”表示,箭頭指向被“use”的類。

在C++代碼中,依賴關(guān)系是這樣對應(yīng)的:
class A
{ public: B returns_a_B();
void has_a_B_argument(B);
void has_a_B_in_its_implementation();
};
A::void has_a_B_in_its_implementation(){ B b; }
2、關(guān)聯(lián)(Association)
關(guān)聯(lián)可以表述成一個類“知道”另一個類。如何“知道”呢?在C++中,類A“知道”類B一般是通過指針實(shí)現(xiàn)的(也可以使用引用或者值),即類A有一個成員變量是指向B的指針(或者引用、值)。
關(guān)聯(lián)可以分為雙向關(guān)聯(lián)、單向關(guān)聯(lián)、自身關(guān)聯(lián)。
1)雙向關(guān)聯(lián)
雙向關(guān)聯(lián)A-B:雙方都“知道”對方,都可以調(diào)用對方的公共屬性和方法。

對應(yīng)的C++代碼為:
class A {
public:
B* pB;
};
class B {
public:
A* pA;
};
2)單向關(guān)聯(lián)
單向關(guān)聯(lián)A->B:表示A“知道”B,A可以調(diào)用B的公共屬性和方法。沒有生命周期的依賴。

對應(yīng)的C++代碼為:
class A {
public:
B* pB;
};
class B {
};
3)自身關(guān)聯(lián)
自身關(guān)聯(lián):自己引用自己,這個在鏈表中非常常見。
可以看到,上面的Object類,就是一個自身關(guān)聯(lián)的應(yīng)用,它有一個自己指向自己的指針,用來實(shí)現(xiàn)鏈表。

對應(yīng)的C++代碼為:
class Object {
public:
int data;
Object* next;
};
class ObjectList {
public:
Object* first;
ObjectList();
void insert(Object* obj);
void print() const;
};
3、聚合(Aggregation)和組合(Composition)
聚合和組合都是用在表述整體-部分關(guān)系的時候,二者只是在生命周期問題上有差異。
1)聚合通常可以理解成“has a”關(guān)系。如果類A聚合類B,那么類A“has a”類B,同時,在A的生命周期結(jié)束后類B必須依然存在或者有意義。比如房間有一張桌子,那么房間和桌子的關(guān)系就是聚合:即使房間沒有了,那張桌子還是存在的,桌子是可以脫離房間而存在的。

對應(yīng)的C++代碼:
class Table {
};
class Room {
public:
Table aTable;
};
2)組合通常可以理解為“is a part of”。和聚合不同的是,如果類A組合類B,那么當(dāng)A生命周期結(jié)束后,類B也隨之結(jié)束,也就是說B不能脫離類A而存在。就如同鳥都有兩只翅膀一樣,當(dāng)鳥消失了,翅膀也隨之不存在了。

對應(yīng)的C++代碼:
class Wing {
};
class Bird{
public:
Wing leftWing;
Wing rightWing;
};
可以發(fā)現(xiàn),如果單純從C++代碼來看,聚合關(guān)系和組合關(guān)系沒有什么不同,要區(qū)分聚合和組合,只能從語義分析。
補(bǔ)充:
組合關(guān)系還有另一層含義:“is a”。不過這種含義,僅僅用來角色方面,即“is a”角色。比如一個人,是丈夫角色。那也可以看做組合;手機(jī)可以看做“Camera”、“Music Player”等。

從上圖我們可以看出,Battery和Smart Phone是聚合關(guān)系,因?yàn)殡姵厥鞘謾C(jī)的一部分,但是電池可以脫離手機(jī)而存在。而IMEI Number和Smart Phone是組合關(guān)系,一般情況下一個Smart Phone只有一個IMEI Number,手機(jī)消失后,IMEI跟著消失。而我們知道現(xiàn)在的手機(jī)可以拍照、上網(wǎng)、播放音樂,因此手機(jī)可以扮演相機(jī)、web沖浪、音樂播放器的角色,所以Smart phone和Camera、Web Browser、Music Player是組合的關(guān)系。
4、泛化(Realization)
泛化關(guān)系也被常用作繼承(inherit)關(guān)系,是用來表述“Is-a”這種關(guān)系的,比如Car和Police-Car的關(guān)系,Police-Car “is a” Car。

對應(yīng)的C++代碼為:
class Car {
};
class Police_Car{
};