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++好的物件導向軟體

相關的慣用語

编辑

參考

编辑

C++ Interface Classes - An Introduction