C++入门学习笔记5:数据抽象与数据封装
- Sunny
- 0
从抽象起就算是正式接触模块化编程了。
抽象的定义
抽象是指在程序中只向外界提供关键信息,而隐藏后台的实现细节,即只表现必要的信息而不呈现细节。
就 C++ 编程而言,C++ 类为数据抽象提供了可能。它们向外界提供了大量用于操作对象数据的公共方法,也就是说,外界实际上并不清楚类的内部实现。
在 C++ 中,我们使用类来定义我们自己的抽象数据类型(ADT)。简单的说,我们使用类iostream
的cout
来打印文本信息,但实际上我们并不知道是怎么实现在屏幕上打印相关信息的。
#include <iostream>
using namespace std;
int main() {
cout<<"hello world!"<<endl; //打印的具体实现过程我们并清楚
return 0;
};
封装的定义
所有的 C++ 程序都有以下两个基本要素:
- 程序语句(代码):这是程序中执行动作的部分,它们被称为函数。
- 程序数据:数据是程序的信息,会受到程序函数的影响。
封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据封装引申出了另一个重要的 OOP 概念,即数据隐藏。
数据封装是一种把数据和操作数据的函数捆绑在一起的机制,数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制。
理解
从上面看到这里,晕了吗?晕就对了,因为我也不知道这样的一段话说的到底是什么,只是原封不动的把书本上的话摘抄了下来,那么我们就用大白话来理解一下这段非人类语言吧:
所谓数据抽象,其实就是找出共性。比如,手机店由很多牌子的手机,由小米、华为、vivo、oppo、、金立等等等等,我们通过抽象,归纳出这些手机的共性:他们都是智能机。智能机就相当于是一个接口。
同时数据抽象会暴露接口,同时隐藏实现细节,我们回到刚才的手机话题,这些手机都是智能机,但为什么有的手机能卖8000有的手机却充话费就可以送呢?这就是在于内部细节的不同,但这些内部细节我们凭肉眼是看不到的,因此诸如主板、处理器、基带、内存这类的细节就被隐藏了。
因此,我们说数据抽象是一种依赖接口与实现分离的编程技术(概念)
那么什么又是数据封装呢?我们继续刚才的手机话题,我相信现在大家买手机都会优先考虑智能机(除了个别特殊需求的人群),那么在这个基础上我们再考虑手机性能,诸如处理器到底是高通还是海思,又或者是联发科还是其他等等,那么这就类似于C++编程的数据抽象了。
刚才我们提到,智能机是接口,各类智能机的具体配置参数是实现,我们再挑选手机时,先定义一个“类”class
来定义智能机,用C++的教程来说就是定义一个抽象数据类型来实现封装,然后这个类中声明各种配置部件名。这时候我们再挑选手机的时候只需要根据这个类逐个创建对象,进行比较。即类的设计者只需要考虑类的内部是如何实现的,类的使用者只需要考虑接口如何使用。
上面提及了这么多次的接口和实现,那么我们也顺带提一下他们的概念吧。
接口是指类对象所能执行的操作,实现就是指接口函数的定义、类的数据成员以及实现类所需的其余私有成员函数。
封装的好处
封装隐藏了细节,避免了用户级错误操作而更改对象状态,当有新的需求时,只需要修改类的内部,无需修改接口,那么用户级代码可以动,只需重新编译即可运行,极大提高开发效率,降低维护成本。
实例
#include <iostream>
using namespace std;
class Adder{
public:
// 构造函数
Adder(int i = 0) {
total = i;
}
// 对外的接口
void AddNum(int number) {
total += number; //total值加number值重新赋值给total
}
// 对外的接口
int getTotal(){
return total;
}
private:
int total;
};
int main(){
Adder a;
a.AddNum(10);
cout << a.getTotal() << endl;
a.AddNum(20);
cout << a.getTotal() << endl;
a.AddNum(30);
cout << a.getTotal() << endl;
return 0;
}
输出结果为
10
30
60