什么是面向对象、面向过程?
面向对象主要是把整个需求****按照特定或者功能来划分,将存在共同特性或功能的属性和方法封装成一个类,创建对象后,就可以描述某个事务在解决问题的步骤中的行为。 面向过程就是分析出解决问题所需要的步骤,然后把这些步骤一步一步实现,使用的时候一个一个一次调用就可以了。
面向对象的三大特性
封装
封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别; 将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成**“类”**,其中数据和函数都是类的成员。
继承
继承概念及定义
在保持原有类的特性的基础上进行扩展(将多个类中相同的部分分离出来建立基类(父类))。
继承方式
public继承: 基类中的public成员是派生类中public成员。 基类中的protect成员是派生类中protect成员。 基类中的private成员在派生类中不可见。 protect继承: 基类中的public成员是派生类中protect成员。 基类中的protect成员是派生类中protect成员。 基类中的private成员在派生类中不可见。 private继承: 基类中的public成员是派生类中private成员。 基类中的protect成员是派生类中private成员。 基类中的private成员在派生类中不可见。 注意: 基类中的private成员在派生类中是不可见的(不能对该成员进行访问),也不能再类外进行访问。 基类中protect成员在类外不能访问,但是在派生类中可对该成员进行访问。
继承分类
单继承
一个子类只有一个直接父类时,称这个继承关系为单继承。
多继承
一般多继承
一般多继承就是一个子类有两个及以上的直接父类
菱形继承
菱形继承指的是一个派生类存在两个及以上的直接父类,且这些父类存在一样的基类。
菱形继承存在的问题:数据冗余及二义性。
如何解决数据冗余及二义性?
答:虚拟继承
虚拟继承的原理
将继承体系中的同名变量统一成一个变量,放在公共区域,存在同名变量的类都会保存一个虚基表指针,当访问时会通过自己类中的虚基表指针所保存的偏移量来获取公共区域的同名变量。
多态
多态的概念及定义
多态指的是完成一个动作,不同的对象去完成都会产生不同的结果
实现多态的条件
1、类之间的关系必须是继承关系。 2、被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。 通过父类的指针或引用调用虚函数。
多态的实现原理
当父类中存在虚函数,子类在继承父类时也会将父类的虚表指针继承过来,父类和子类发生重写时,子类的虚函数指针会覆盖掉虚表中对应重写的 虚函数指针,当父类指针指向子类对象调用重写的虚函数,会通过子类对象中的虚函数指针找到虚表,再通过虚表找到对应的虚函数的地址,最后执行虚函数,产生多态行为。
关于虚表指针、虚表、虚函数
虚表是在编译阶段确定的,存放的是虚函数指针——虚函数地址 虚函数是在运行阶段确定的,存放在代码段 虚表指针是在运行阶段确定的,指向虚表
虚函数重写
派生类中含有和基类中完全一样的虚函数(返回值类型、函数名、参数列表完全相同)
虚函数中的两个例外
协变(返回值不同)和析构函数的重写
为什么析构函数一定要是虚函数?
将基类中的析构函数设置为虚函数,可以保证我们使用父类指针指向子类对象时,在释放父类指针的同时也能释放子类的空间,防止内存泄漏。
内联函数能是虚函数吗?
内联函数不能是虚函数,因为内联函数没有函数地址,不能保存在虚表中
static函数能是虚函数吗?
static函数不能是虚函数,因为static函数没有this指针,无法访问虚表。
|