封装
封装目的:模块化+信息隐藏
封装:隐藏对象的属性和实现细节,仅对外公开接口和对象进行交互,将数据和操作数据的方法进行有机结合。 是通过特性和行为的组合来创建新数据类型让接口与具体实现相隔离。
C++中是通过类来实现的, 为了尽量避免某个模块的行为干扰同一系统中的其它模块,应该让模块仅仅公开必须让外界知道的接口。
继承
继承的目的:实现代码的重用、扩充
继承的步骤:
1、吸收基类成员(父类的全部成员除了构造函数和析构造函数)
2、改造基类成员(重写和重定义)
3、添加新的成员
继承的方式:public、 protected、 private(默认)
public(公有继承):父类中public类型的成员会被继承到子类的public中去,而父类的protected成员也会被继承到子类的protected中去
protected(保护继承):父类中无论是public的还是protected的成员都会被继承到子类的protected中去
private(私有继承):父类中 public 和 protected 的成员都会被继承到子类的private中去(实际相当于阻断了基类功能的继续派生)
派生类和基类的关系:
1. 派生类对象存储了基类的数据成员
2. 派生类对象可以使用基类的方法
派生类和基类的特殊关系:
1.基类指针可以在不进行显式类型转换的情况下指向派生类对象;
2.基类引用可以在不进行显式类型转换的情况下引用派生类对象;
多继承
多继承(Multiple inheritance),即一个子类可以有多个父类,它继承了多个父类的特性。多继承可以看作是单继承的扩展。所谓多继承是指派生类具有多个基类,派生类与每个基类之间的关系仍可看作是一个单继承。
继承下的构造函数:多继承形式下的构造函数和单继承形式基本相同,只是要在派生类的构造函数中调用多个基类的构造函数。基类构造函数的调用顺序和和它们在派生类构造函数中出现的顺序无关,而是和声明派生类时基类出现的顺序相同。
命名冲突:当两个或多个基类中有同名的成员时,如果直接访问该成员,就会产生命名冲突,编译器不知道使用哪个基类的成员。这个时候需要在成员名字前面加上类名和域解析符,以显式地指明到底使用哪个类的成员,消除二义性。
虚基类及其作用
引入虚基类的原因:如果一个派生类有多个直接基类,而这些直接基类又有一个共同基类,则最后的派生类中会保留其直接基类所继承的共同基类的多份同名成员,而引用这些同名的成员时,必须在派生类对象名后增加直接基类名以免产生二义性。占用大量的存储空间,易出错。
将共同基类设置为虚基类,这样从不同派生类继承来的同名数据成员在内存中就只有一个拷贝,同名函数也只有一种映射。维护一份成员副本
为了保证虚基类在派生时只被继承一次,应当在该基类的所有直接派生类中声明为虚基类,否则仍然会出现对基类的多次继承。
实现继承和接口继承
普通函数的继承是实现继承,派生类继承了基类函数,可以使用函数,继承的是函数的实现。
虚函数的继承是一种接口继承,派生类继承的是基类虚函数的接口,目的是为了重写达成多态,继承的是接口。所以如果不实现多态,不要把函数定义成虚函数。
多态
多态的目的:接口重用
多态指同样的消息被不同类型的对象接收时导致不同的行为。
多态分为:静态多态和动态的多态。
静态多态:编译器在编译期间完成的,编译器会根据实参类型来推断该调用哪个函数,如果有对应的函数,就调用,没有则在编译时报错。
动态多态:其实要实现动态多态,需要几个条件——即动态绑定条件:
1、虚函数。基类中必须有虚函数,在派生类中必须重写虚函数。
2、通过基类类型的指针或引用来调用虚函数。
什么是动态特性?
在绝大多数情况下, 程序的功能是在编译的时候就确定下来的, 我们称之为静态特性。 反之, 如果程序的功能是在运行时刻才能确定下来的, 则称之为动态特性。C++中, 虚函数,抽象基类, 动态绑定和多态构成了出色的动态特性。
多态的种类及不同种类介绍
1>强制多态:强制类型转换
强制多态是指将一种类型的值转换为另一种类型的值进行语义操作,从而防止类型错误。类型转换可以是隐式的,在编译时完成;也可以是显式的,可在动态运行时完成。
2>参数类型多态: 函数模板和类模板
参数多态与类模板相关联,它把功能相似仅数据类型(或类类型)不同的函数或类类设计为通用的函数模板或类模板,从而实现了相同的函数或类的成员函数对多种数据类型的数据处理。
泛型编程:编写与类型无关的通用代码,是代码复用的一种手段,模板是泛型编程的基础.
3>重载多态(函数重载):函数名相同,但参数类型和参数个数顺序不同构成的多态
重载多态是多态性中最简单的形式,它分为函数重载和运算符重载。
1.函数重载
函数重载允许功能相近的函数使用相同的函数名,编译器根据参数列表的不同区别不同函数。
2.运算符重载
运算符重载是对已存在运算符赋予多重含义,同一个运算符作用于不同的类型数据导致不同类型的行为,它的实质是函数重载。
4>包含多态(运行时多态、虚函数重写实现、虚方法的动态联编):
包含多态的及实现包含多态的构成条件:
1.基类中必须包含有虚函数,在派生类中必须对基类中的虚函数进行重写。
2.必须通过基类的指针或者引用来调用虚函数。
参考链接四种类型的多态详解
虚函数和动态绑定的关系?
虚函数是动态绑定的基础,虚函数是为了实现运行过程中的多态。
只有通过基类的指针或者引用调用虚函数时,才会发生动态绑定。
基类的指针可以指向派生类的对,基类的引用可作为派生类对象的别名。
抽象
抽象类的作用?
包含纯虚函数的类叫抽象类(也叫接口),抽象类不能实例化,但是可定义抽象类的指针和引用,发挥动态特性。
抽象类作为一个类族的公共接口,通过接口的完整实现(即派生类编写纯虚函数体)--->>接口调用实现动态特性。(一个函数指针可以被赋予不同函数的入口地址,实际被调用的函数一般到了运行时才能确定)
类与对象的区别?
类与对象的区别,如人类与张三的区别,它们是一般与个体、抽象与具体、集体与个体的区别。