Cplusplus 简明教程

Interfaces in C++ (Abstract Classes)

接口描述 C++ 类的行为或功能,而不承诺该类的特定实现。

C++ 接口使用 abstract classes 实现,且这些抽象类不应与数据抽象混淆,数据抽象是一个将实现细节与关联数据分开的概念。

通过将至少一个函数声明为 pure virtual 函数,可以使一个类变为抽象类。纯虚函数通过在其声明中放置 “= 0” 来指定,如下所示 −

class Box {
   public:
      // pure virtual function
      virtual double getVolume() = 0;

   private:
      double length;      // Length of a box
      double breadth;     // Breadth of a box
      double height;      // Height of a box
};

abstract class (通常称为 ABC)的目的是提供一个合适的基类,其他类可以从中继承。抽象类不能用于实例化对象,只用作 interface 。尝试实例化抽象类的对象会引发编译错误。

因此,如果需要实例化 ABC 的子类,则它必须实现每个虚函数,这意味着它支持由 ABC 声明的接口。如果在派生类中未重写纯虚函数,然后尝试实例化该类的对象,则会发生编译错误。

可以用来实例化对象的类称为 concrete classes

Abstract Class Example

考虑以下示例,其中父类为基类提供一个接口来实现一个称为 getArea() 的函数 −

#include <iostream>

using namespace std;

// Base class
class Shape {
   public:
      // pure virtual function providing interface framework.
      virtual int getArea() = 0;
      void setWidth(int w) {
         width = w;
      }

      void setHeight(int h) {
         height = h;
      }

   protected:
      int width;
      int height;
};

// Derived classes
class Rectangle: public Shape {
   public:
      int getArea() {
         return (width * height);
      }
};

class Triangle: public Shape {
   public:
      int getArea() {
         return (width * height)/2;
      }
};

int main(void) {
   Rectangle Rect;
   Triangle  Tri;

   Rect.setWidth(5);
   Rect.setHeight(7);

   // Print the area of the object.
   cout << "Total Rectangle area: " << Rect.getArea() << endl;

   Tri.setWidth(5);
   Tri.setHeight(7);

   // Print the area of the object.
   cout << "Total Triangle area: " << Tri.getArea() << endl;

   return 0;
}

编译并执行上述代码后,将产生以下结果 −

Total Rectangle area: 35
Total Triangle area: 17

你可以看到抽象类如何以 getArea() 的形式定义接口,以及其他两个类使用不同的算法来计算特定形状的区域,但它们实现的是同一个函数。

Designing Strategy

面向对象系统可能使用抽象基类来为所有外部应用程序提供一个通用和标准化的接口。然后,通过从该抽象基类继承,将形成以类似方式工作的派生类。

外部应用程序提供的功能(即,公有函数)作为抽象基类中的纯虚函数。这些纯虚函数的实现由对应于应用程序特定类型的派生类提供。

此架构还允许在新系统定义后轻松地向其中添加新的应用程序。