一、封装
面向对象有三大特性,在前面分析过了继承和多态。在有了前面的知识储备后,今天分析一下另外一个特性,封装。对于封装,可能很多开发者特别是初学者,不觉得它有什么让人不好掌握的地方或者说它重要在哪里。其实,恰恰是这种看上去简单的东西,往往更难于掌握,更难于应用好。
先举一个现实的例子,现代物流业非常发达,人们经常会把各种形状大小的物品通过快递或其它方式发送到全球各地,这些小东西最终会被汽车,火车拉到港口,然后装船运往全球的港口,再卸下分装到火车和汽车再运送到目的地。但是这种大小不同、重量不等甚至形状各异的物品在运输过程中很有可能安放、排列等都非常不方便。特别是对于大型的货船来说,每次的装卸都是一个异常耗时的过程。这时候儿有聪明人想到了,为啥不把火车的车厢和汽车的车厢直接搬到船上,这样不就方便了装卸么?于是有人把车厢进行了标准化,这就是集装箱。
事实也是如此,现代物流可以说已经无法离开集装箱了。那集装箱为什么能够流行呢?简单的说,就是标准和效率。由于物流运输不再考虑具体的物品的大小形状重量,而针对封装这些物品的集装箱,这就大减轻了运输过程中的细节的处理(比如火车上大家经常听到,大不压小,重不压轻,诸如此类),运输效率自然大增。
那么什么是封装(Encapsulation)呢?一般来说,封装是指将数据和操作数据的方法也就是把数据和行为整合在一起,形成一个独立的单元即常说的类(或结构体)。对外隐藏内部的实现细节,只暴露应该提供的接口。
对比看一看,和集装箱是不是有些类似?
二、封装的意义
封装是编程的最基础的功能或者说最基本的方法,它是展开面向对象或其它一些编程范式的前提。封装在实际的应用中,提供了代码安全性的保障,防止出现意外的数据访问和操作;封装还提供了良好的接口和便捷的扩展性;在此基础上,进一步提高了代码整体的可靠性。而同类型的封装又引入了可靠的代码复用,而内部实现细节的隐藏又提高了后期代码的可维护性。
同样重要的是,封装也为OOP的另外两个特性继承和多态提供了根本的支持即封装是抽象方法的一种具体的手段。
封装在提供了上述的支撑外,还可以进一步扩展到不同的编程环境中进行灵活的设计和开发(比如设计模式、后台服务等),对提高编程整体的水平有着非常重要的意义。
三、如何封装
刚刚也提到了,封装是一种看上去简单,其实则非常考验开发者或设计者能力的一种能力,也就是最终它落在了开发者的思想水平的境界上。举一个不恰当的例子,在修仙界类别的小说中,经常有不同的等级,比如金丹期和筑基期使用同一个法宝,那产生的威力不可同日而语。所以封装要想做得更好的,只有反复不断的提高自己的编程思想才是根本。
不过,封装也是有一些基本的方法的,不然,思想这东西看不到摸不着,不就成了玄学了。
1、从形成上可以使用不同的修饰符来划分对外暴露的等级:
public(公有):完全开放,任何代码都可以访问
private(私有):仅类内部可以访问
protected(保护):类内部和子类可以访问
2、归类处理
这种方法和现实世界一样,把相同的功能的或类似的功能(行为或数据以及操作等)的实现封装在一起。比如汽车类里就可以有车轮、方向盘、发动机等。颜色的封装就可以有赤、橙、黄等等。
3、接口与实现分离
这是比较容易感官上对开发者看到的,将具体的实现细节和对外的暴露接口分离,开式上它也可以体现为接口和类的封装;也可以理解为头文件和实现文件分离。
总之,封装的重要性是不言而喻的,开发者也不必急于一时。哪个人的成长不是从跌跌撞撞的爬行一路到奔跑。
四、应用实例
封装的例子非常多,不说别的,教科书的例子就海了去了,更别提什么其它的资料和网页上了。但总得有一个例子对照说明吧。
//.h
class MyAccount {
private:
double balance = 0.0;
public:
MyAccount(double b);
double getBalance() const;
void deposit(double amount);
void withdraw(double amount);
};
//.cpp
MyAccount::MyAccount(double b) : balance(b) {}
double MyAccount::getBalance() const {
return balance;
}
void MyAccount::deposit(double amount) {
if(amount > 0) balance += amount;
}
void MyAccount::withdraw(double amount) {
if(amount > 0 && amount <= balance) balance -= amount;
}
例子非常简单,不做说明了。
五、总结
“基础不牢,地动山摇”,侯捷老师也在他的书上写道“勿在浮砂筑高台”,其实都是一个意思。只有把基础掌握了,才是成为高手的第一步。一个再学习过很多高明的剑招的人,如果从来没有和人比拼过,那么,他肯定不是一个高手。