More C++ Idioms/介面類別
介面類別(Interface Class)
編輯
目的
編輯- 從實作分離出類別的介面。
- 藉由執行期間多型(runtime polymorphism)喚起抽象類(abstraction)的成員函數。
別名
編輯動機
編輯從實作分離出介面類別是好的物件導向設計或程式的基石。對於物件導向程式,分離的主要機制是介面類別。然而, C++(當與Java比較)並沒有提供專有的描述這樣的分離機制。在Java,關鍵字interface
用於規定只有抽象的成員函數。 C++ 並沒有這樣的關鍵字,但其功能表示接近使用介面類別(Interface Class)慣用語。其想法是只有抽象的成員函數,並且並沒有提供任何實作。此外,實作的缺乏指沒有實體的介面類別應該被允許。
解決方案與範例程式
編輯介面類別只有包含虛擬解構式和純虛擬函數,因此提供類似於其他語言(例如:Java)介面的構件。介面類別是一個類別規定多型的介面,例如:純虛擬函數宣告式是父類別。使用類別階層的程式設計師可以透過父類別操作,在階層溝通只能透過類別們的介面。
class shape // 一個介面類別
{
public:
virtual ~shape();
virtual void move_x(int x) = 0;
virtual void move_y(int y) = 0;
virtual void draw() = 0;
//...
};
class line : public shape
{
public:
virtual ~line();
virtual void move_x(int x); // 實作 move_x
virtual void move_y(int y); // 實作 move_y
virtual void draw(); // 實作 draw
private:
point end_point_1, end_point_2;
//...
};
int main (void)
{
std::vector<shape *> shapes;
// 以某種方式塞滿指標向量容器shapes。
for (vector<shape *>::iterator iter (shapes.begin());
iter != shapes.end();
++iter)
{
(*iter)->draw();
}
// 清理指標向量容器shapes。 (一般來說,我將使用智能指標像boost::shared_ptr去自動清理,
// 這邊只是為了解釋)
}
每一個介面類別應該有一個虛擬解構式 。當刪除多型指標時,虛擬解構式確保喚起子類別的正確解構式。否則,將有可導致資源洩漏。使用介面類別設計有許多好處:
- 加入新抽象類別
Shape
不會改變程式碼,而是取決於介面類別。例如:Square
繼承Shape
,然後用自己的方法實作介面虛擬函數。在函數main()
不需要改變。 - 從實作分離出介面類別防止依賴在介面類別的部分程式重新編譯。
- 依賴倒轉原則(Interface Class,DIP )描述類別實作不應該依賴其他人。反而,他們應該依賴共同抽象類別,此類別可用介面類別所表示。DIP將減少物件導向系統的耦合性。
已知應用
編輯幾乎所有使用C++好的物件導向軟體