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