C++ 中的接口(抽象类)
接口描述 C++ 类的行为或功能,但不指定该类的具体实现。
C++ 接口使用抽象类实现,这些抽象类不应与数据抽象混淆,数据抽象是将实现细节与关联数据分离的概念。
通过将类中的至少一个函数声明为纯虚函数,类就变成了抽象类。纯虚函数的声明方式是:在类声明中加上"= 0",如下所示:
class Box { public: // 纯虚函数 virtual double getVolume() = 0; private: double length; // Box 的长度 double breadth; // Box 的宽度 double height; // Box 的高度 };
抽象类(通常称为 ABC)的目的是提供一个合适的基类,以便其他类可以继承。抽象类不能用于实例化对象,而只能用作接口。尝试实例化抽象类的对象会导致编译错误。
因此,如果需要实例化 ABC 的子类,它必须实现每个虚函数,这意味着它支持 ABC 声明的接口。如果在派生类中未重写纯虚函数,然后尝试实例化该类的对象,则会导致编译错误。
可用于实例化对象的类称为具体类。
抽象类示例
请考虑以下示例,其中父类为基类提供了一个接口,以实现名为 getArea() 的函数 -
#include <iostream> using namespace std; // 基类 class Shape { public: // 提供接口框架的纯虚函数。 virtual int getArea() = 0; void setWidth(int w) { width = w; } void setHeight(int h) { height = h; } protected: int width; int height; }; // 派生类 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); // 打印对象的面积。 cout << "Total Rectangle area: " << Rect.getArea() << endl; Tri.setWidth(5); Tri.setHeight(7); // 打印对象的面积。 cout << "Total Triangle area: " << Tri.getArea() << endl; return 0; }
当编译并执行上述代码时,它会产生以下结果 -
Total Rectangle area: 35 Total Triangle area: 17
您可以看到,一个抽象类如何根据 getArea() 定义一个接口,而另外两个类如何实现相同的函数,但使用不同的算法来计算特定形状的面积。
设计策略
面向对象系统可能会使用一个抽象基类来提供适用于所有外部应用程序的通用标准化接口。然后,通过从该抽象基类继承,可以形成具有类似操作的派生类。
外部应用程序提供的功能(即公共函数)在抽象基类中以纯虚函数的形式提供。这些纯虚函数的实现在与应用程序特定类型对应的派生类中提供。
即使在系统定义之后,这种架构也允许轻松地将新的应用程序添加到系统中。