類封裝了數據和行為,是面向對象的重要組成部分,它是具有相同屬性、操作、關系的對象集合的總稱。在系統中,每個類都具有一定的職責,職責指的是類要完成什么樣子的功能,要承擔什么樣子的義務。一個類可以有多種職責,但是設計得好的類一般只有一種職責。
類與類之間的關系
繼承關系
繼承也叫作泛化(Generalization),子類(派生類)繼承父類(基類)的屬性和方法,并可擴展或重寫父類功能。
C++ 中沒有專門的 “接口” 關鍵字,通常用純虛基類模擬接口,子類通過?public
?繼承該純虛類并實現其所有純虛函數。
class Bird
{
public:string getName(){return m_name;}void setName(string name){m_name = name;}virtual void fly() {}virtual void eat() {}
protected:string m_sex;string m_name;
};class Cuckoo : public Bird
{
public:void fly() override{cout << "我拍打翅膀飛行..." << endl;}void eat() override{cout << "我喜歡吃肉肉的小蟲子..." << endl;}
};class Eagle : public Bird
{
public:void fly() override{cout << "我展翅翱翔..." << endl;}void eat() override{cout << "我喜歡吃小動物..." << endl;}
};
?組合關系
組合(Composition)表示 “整體 - 部分” 關系,部分完全依賴整體存在(強包含)。
部分不能脫離整體獨立存在,整體的生命周期決定部分的生命周期(整體創建時部分被創建,整體銷毀時部分也被銷毀),部分只能屬于一個整體。
例如人和心臟:心臟是人的一部分,人死亡后心臟也不再獨立存在。
class Heart {
public:void beat() {}
};
class Person {
private:Heart heart; // 組合關系(部分作為成員變量,隨整體創建/銷毀)
public:Person() : heart() {} // 構造時創建心臟
};
?聚合關系
聚合(Aggregation)表示 “整體 - 部分” 關系,部分可脫離整體獨立存在(弱包含)。
整體通過成員變量持有部分的指針 / 引用,整體包含部分,但部分的生命周期不由整體控制,部分可屬于多個整體。
比如公司和員工:員工是公司的一部分,但員工可離職(脫離公司存在)。
class Employee {};
class Company {
private:std::vector<Employee*> employees; // 聚合員工(部分)
public:void addEmployee(Employee* e) {employees.push_back(e);}
};
關聯關系
表示兩個類之間存在長期、穩定的連接,通常體現為一個類持有另一個類的對象引用(或指針)。
關系可單向或雙向(如 A 關聯 B,或 A 與 B 相互關聯),類之間生命周期相互獨立,關聯不影響對象的創建與銷毀。
單向關聯
單向關聯指的是關聯只有一個方向,比如每個孩子都擁有一個Parent,其代碼實現為:
class Parent
{
};class Child
{
private:Parent m_father;
};
雙向關聯
現實生活中每個孩子都有父母,每個父母同樣有自己的孩子,如果想要通過類來描述這樣的親情關系,代碼如下:
class Parent
{
private:Child* m_son;
};class Child
{
private:Parent* m_father;
};
自關聯
自關聯指的就是當前類中包含一個自身類型的對象成員,這在鏈表中非常常見,單向鏈表中都會有一個指向自身節點類型的后繼指針成員,而雙向鏈表中會包含一個指向自身節點類型的前驅指針和一個指向自身節點類型的后繼指針。就以雙向鏈表節點類為例,它的C++寫法為:
class Node
{
private:void* m_data;Node* m_prev;Node* m_next;
};
?依賴關系
表示一個類(依賴方)在執行特定操作時,臨時需要另一個類(被依賴方)的協助,是一種短期的 “使用” 關系。
通常通過方法參數、局部變量或靜態方法調用體現,無長期持有關系,操作結束后依賴消失。
例如計算器計算時需要臨時使用數字Number
對象:
class Number {
public:int value;
};
class Calculator {
public:// 通過參數依賴 Numberint add(Number a, Number b) { return a.value + b.value; }
};
總結
類之間的關系強弱順序是這樣的:繼承(含接口實現)?>??組合??>??聚合??>??關聯??>??依賴。
在實際設計中,應優先使用低耦合關系(如關聯、聚合、組合),避免過度依賴繼承,以提高代碼的靈活性和可維護性。