数据抽象
数据抽象是只提供相应的接口,而不是提供具体的实现细节,例如sqrt()函数,我们只需要使用相应的接口就能够使用这个函数,不管这个函数是如何处理的,例如,每个类中的函数都是数据抽象,我们只需知道如何使用以及他的功能就可以,而无需管他是如何实现
例子:
#include <iostream>
using namespace std;
class Adder{
public:
// 构造函数
Adder(int i = 0)
{
total = i;
}
// 对外的接口
void addNum(int number)
{
total += number;
}
// 对外的接口
int getTotal()
{
return total;
};
private:
// 对外隐藏的数据
int total;
};
int main( )
{
Adder a;
a.addNum(10);
a.addNum(20);
a.addNum(30);
cout << "Total " << a.getTotal() <<endl;
return 0;
}
设计策略:抽象把代码分离为接口和实现。所以在设计组件时,必须保持接口独立于实现,这样,如果改变底层实现,接口也将保持不变。
在这种情况下,不管任何程序使用接口,接口都不会受到影响,只需要将最新的实现重新编译即可。
数据封装
数据封装是一种把数据和操作数据的函数捆绑在一起的机制,数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制。
C++ 通过创建类来支持封装和数据隐藏(public、protected、private)。我们已经知道,类包含私有成员(private)、保护成员(protected)和公有成员(public)成员。默认情况下,在类中定义的所有项目都是私有的。例如:
#include <iostream>
using namespace std;
class Adder{
public:
// 构造函数
Adder(int i = 0)
{
total = i;
}
// 对外的接口
void addNum(int number)
{
total += number;
}
// 对外的接口
int getTotal()
{
return total;
};
private:
// 对外隐藏的数据
int total;
};
int main( )
{
Adder a;
a.addNum(10);
a.addNum(20);
a.addNum(30);
cout << "Total " << a.getTotal() <<endl;
return 0;
}
设计策略:把不想暴露的东西使用private或者protected来保护起来,使之只能通过函数来访问
接口(抽象类)
C++的接口是通过抽象类来实现的,所谓抽象类就是类中包含一个纯虚函数
int test(int a)=0;
纯虚函数在上一节已经提到过了,就是不能够实例化,在每个派生类中,与基类中的纯虚函数相同的函数都要重新定义,这样声明基类的指针,并将派生类的地址赋值给基类的指针之后,输出的就是派生类中的函数,注意,如果是派生类的地址赋值给派生类的指针,就算没有虚函数,一样使用的是派生类的函数。