C++ 菜鸟教程之接口(抽象类)

缘起

RT

分析

先看一个例子

panta.cpp

1
2
3
4
5
6
7
8
9
10
11
12
#include "stdafx.h"
#include<iostream>
#include "AClass.h"

using namespace std;

int main(){
Aclass aClass;
aClass.setLength(10);
cout << aClass.getLength()<<endl;
return 0;
}

AClass.h

1
2
3
4
5
6
7
8
9
10
class Aclass
{
public:
Aclass();
int getLength();
void setLength(int);

private:
int length;
};

Aclass.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "stdafx.h"
#include "AClass.h"
#include <iostream>
using namespace std;

Aclass::Aclass()
{
cout << "AClass创建成功"<< endl;
}

void Aclass::setLength(int length)
{
this->length = length;
}

int Aclass::getLength()
{
return length;
}

可见,AClass.h 类似于java中的接口, 而AClass.cpp 就是 AClass.h接口的实现.

接口描述了类的行为和功能,而不需要完成类的特定实现。

C++ 接口是使用抽象类来实现的,如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明中使用 “= 0” 来指定的,如下所示:

1
2
3
4
5
6
7
8
9
10
class Box
{
public:
// 纯虚函数
virtual double getVolume() = 0;
private:
double length; // 长度
double breadth; // 宽度
double height; // 高度
};

设计抽象类(通常称为 ABC)的目的,是为了给其他类提供一个可以继承的适当的基类。抽象类不能被用于实例化对象,它只能作为接口使用。如果试图实例化一个抽象类的对象,会导致编译错误。

因此,如果一个 ABC 的子类需要被实例化,则必须实现每个虚函数,这也意味着 C++ 支持使用 ABC 声明接口。如果没有在派生类中重写纯虚函数,就尝试实例化该类的对象,会导致编译错误。

可用于实例化对象的类被称为具体类

抽象类的实例

请看下面的实例,基类 Shape 提供了一个接口 getArea(),在两个派生类 Rectangle 和 Triangle 中分别实现了 getArea()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#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;
}

当上面的代码被编译和执行时,它会产生下列结果:

1
2
Total Rectangle area: 35
Total Triangle area: 17

从上面的实例中,我们可以看到一个抽象类是如何定义一个接口 getArea(),两个派生类是如何通过不同的计算面积的算法来实现这个相同的函数。