一、接口描述
接口描述了一个 C++ 类的行为或能力,但并不承诺特定的实现。C++ 接口是通过抽象类实现的,这些抽象类不应与将实现细节与相关数据分离的概念——数据抽象混淆。
一个类通过声明至少一个纯虚函数来使其成为抽象类。纯虚函数通过在其声明中放置 "= 0" 来指定,如下所示:
class Box {
public:
virtual double getVolume() = 0;
private:
double length;
double breadth;
double height;
};
抽象类(通常称为 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 << "矩形总面积: " << Rect.getArea() << endl;
Tri.setWidth(5);
Tri.setHeight(7);
cout << "三角形总面积: " << Tri.getArea() << endl;
return 0;
}
当上述代码被编译和执行时,它产生了如下结果:
矩形总面积: 35
三角形总面积: 17
你可以看到抽象类如何定义了 getArea() 接口,而另外两个类实现了同一个函数,但采用了不同的算法来计算特定形状的面积。
三、设计策略
面向对象系统可能使用抽象基类来提供一个适用于所有外部应用程序的通用且标准化的接口。然后,通过从该抽象基类继承形成操作相似的派生类。
外部应用程序提供的功能(即公共函数)作为纯虚函数在抽象基类中提供。这些纯虚函数的具体实现则在对应于应用程序特定类型的派生类中提供。
这种架构还允许在系统定义之后轻松地将新的应用程序添加到系统中。