1.封装
突破了C语言函数的概念,封装可以隐藏实现细节,使得代码模块化。
2.继承
继承可以扩展已存在的代码模块(类);达到代码重用的目的。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。
3.多态
接口重用,多态可以使用未来,即当前的框架不需改变也可以使用后来的代码。
封装可以隐藏实现细节,使得代码模块化;封装是把成员变量和成员函数封装起来,对成员变量的访问只能通过成员函数。c++类中不要留有public 成员变量,应当在设计时提供一组读写其的成员函数。C#,java中都是使用属性代替了public 成员变量。
继承的实现方式有三类:实现继承、接口继承和可视继承。
1. 实现继承是指使用基类的成员变量和成员函数而无需额外编码的能力;(注:private修饰的部分也会被继承,只是使用不了)
2. 接口继承是指仅使用成员变量和成员函数的名称、但是子类必须提供实现的能力
3. 可视继承是指子窗体(类)使用基窗体(类)的外观和实现代码的能力
多态性(polymorphisn)允许将子类类型的指针赋值给父类类型的指针。
多态的实现方式
函数重载
必须在同一个类中进行
子类无法重载父类的函数,父类同名函数将被名称覆盖
重载是在编译期间根据参数类型和个数决定函数调用
函数重写
必须发生于父类与子类之间
并且父类与子类中的函数必须有完全相同的原型
使用virtual声明之后能够产生多态(如果不使用virtual,那叫重定义)
多态是在运行期间根据具体对象的类型决定函数调用
不同语言如何实现多态机制?
1.按照绝对位置查表-C++,这种方法由于编译阶段已经做好了索引和表项,所以运行速度比较快;缺点是比如:GUI库,以MFC库为例,MFC有很多类,都是一个继承体系;而且很多时候每个类只是1、2个成员函数需要在派生类重写,如果用C++的虚函数机制,每个类有一个虚表,每个表里面有大量的重复,就会造成空间利用率不高。
2.按照函数名称查表-smalltalk等,这种方案可以避免如上的问题;但是由于要比较名称,有时候要遍历所有的继承结构,时间效率性能不是很高。MFC的消息映射机制不用虚函数机制,也是使用的函数名称查表
总结:
时间与空间的换取效率的老问题,c++中通过为每个类维护一张虚函数表实现多态,随着基类virtual函数数量的增大,虚函数表占有的空间也在增大。且当子类继承时如果只是重写很少部分virtual函数功能时,会带来资源浪费。
如果继承体系的基类的virtual成员不多,而且在派生类要重写的部分占了其中的大多数时候,用C++的虚函数机制是比较好的;
但是如果继承体系的基类的virtual成员很多,或者是继承体系比较庞大的时候,而且派生类中需要重写的部分比较少,那就用名称查找表,这样效率会高一些。