继承:
当一个类从另一个 类继承时,可以有3种派生类型:公有型(public)、保护型(protected)和私有型(private)。
继承概念:在原有的类不变的基础之上,新增一些函数,对功能进行拓展。继承说白了就是为了提高程序的可复用性。但是在一个代码中不能过度使用继承,否则会导致代码可读性降低,而且检查出错的时候也难以改正。
继承定义:继承就是在一个已存在的类的基础上建立一个新的类,已存在的类称为基类。新建立的类称为派生类,一个新类从已有的类那里获得已有的特性,这种现象叫继承。派生类继承了父类的全部数据成员和成员函数。
继承语法:
class 派生类名:继承方式 基类名1, 继承方式 基类名2,...,继承方式 基类名n
{
派生类成员声明;
};
继承特点:
(1) 派生类是对基类的扩展,派生类可以添加新的成员,但不能移除已经继承的成员的定义。
(2)继承是可以传递的。如果C从B中派生,B又从A中派生,那么C不仅继承了B中声明的成员,同样也继承了A中声明的成员。
(3)构造函数和析构函数不能被继承,除此之外其他成员能被继承。基类中成员的访问方式只能决定派生类能否访问它们。
(4)派生类如果定义了与继承而来的成员同名的新成员,那么就可以覆盖已继承的成员,但这兵不是删除了这些成员,只是不能再访问这些成员。
(5)类可以定义虚方法、虚属性及虚索引指示器,它的派生类能够重载这些成员,从而使类可以展示出多态性。
(6)派生类只能从一个类中继承,可以通过接口来实现多重继承。
派生类成员的访问属性:
- 公用继承:它的访问限定符是public。基类的公用成员和保护成员(protected)在派生类中成了基类私有成员。
- 私有继承:在声明一个类的时候把继承方式声明为private(私有)的形式,称为私有继承, 派生类称为私有派生类。在基类中的私有成员在私有派生类中是不可访问的,基类的公有成员和保护成员在私有派生类中是私有的。
- 保护继承:基类的公有成员和私有成员都以保护成员的身份出现在派生类中,而基类的私有成员不可访问。派生类的其他成员可以直接访问从基类继承来的公有和保护成员,但是类外部通过派生类的对象无法访问它们,无论派生类的成员还是派生类的对象,都无法访问基类的私有成员。
继承方式下的构造与析构:
基类——>数据成员——>构造
析构——>数据成员——>基类
其中我认为以下情况不合适使用继承:
一、如果类A和类B毫不相关,不可以为了使B的功能更多些而让B继承A的功能。
二、如果类B有必要使用A的功能,则要分两种情况考虑:
(1)若在逻辑上B是A的''一种''(a kind of),则允许B继承A的功能。
(2)若在逻辑上A是B的''一部分''(apart of),则不允许B继承A的功能,而是要用A和其它东西组合出B。
继承体系中的作用域:
1、基类和派生类不是同一块作用域 。
2、同名隐藏问题:因为派生类中有与基类同名的成员,派生类中将隐藏基类的同名成员,不能直接访问,可以通过 (基类名::基类成员)的方式访问。
注意事项:
1、子类继承父类时,如果出现同名方法时,可能会隐藏父类的方法。
2、如果子类隐藏了父类的方法,则父类中所有同名的方法均被隐藏。
3、在派生完一个子类后,可以定义一个 父类的类型指针,通过子类的构造函数为其创建对象。
多态:
原理:
在基类里函数加virtual,在派生类中重写此函数,那么运行时将根据对象的实际类型来调用相应的函数。如果对象是派生类就调用派生类的函数,如果对象是基类就调用基类的函数。
含义:
多态是面向对象语言的重要特性,是指不同对象接收到同一消息时会产生不同的行为。其实多态就是在同一个类或继承体系结构的基类与派生类中,用同名函数来实现不同的功能。多态则是基类使用派生类的方法。一般,我们使用多态是为了避免在基类里大量重载引起代码臃肿且难于维护。
概念:
重写(覆盖):两个函数具有相同函数名,返回类型,参数表。
重载:函数或者方法有相同的名称。
静态多态性:采用静态联编的方式实现的多态,所谓静态联编是通过函数重载和运算符重载实现的。
动态多态性:通过继承和虚函数,在程序执行时通过动态绑定实现的。
多态主要是为了降低程序的耦合度,就是说,写一个类不仅用一次,只能被某个类使用,而且,可以被不同的场景使用,只需要继承和重写就可以了。
虚函数:当基类对象的指针指向派生类对象时,只能通过它访问到派生类中的基类子对象。虚函数只能在类中定义,即只能把类的成员函数声明为虚函数,不属于任何类的普通函数不能被定义为虚函数。
虚函数的运行机制为:如果基类中的非静态成员函数被定义成为虚函数,且当派生类重写了该函数,当通过指向基类对象的指针或引用调用派生类对象中的虚函数时,就会调用该指针实际所指对象的成员函数。一旦将某个成员函数声明为虚函数后,其派生类重写该函数是并没有把它声明为虚函数,它仍然为虚函数。
C++面向对象程序中存在三种多态
1、对象类型的多态:派生类的对象的类型既可以是派生类,也可以是基类,即一个对象可以属于多种类型。
2、对象标识的多态:基类的指针或引用可以指向或引用基类对象,也可以指向或引用派生类对象,即一个对象标识可以属于多种类型,它可以标识多种对象。在对象标识符定义时指定的类型称为它的静态类型,而在运行时实际标识的对象的类型称为它的动态类型。
3、消息的多态:一个可以发送到基类对象的消息,也可以发送到派生类对象,从而可能得到不同的解释。
C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数
1:用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数。
2:存在虚函数的类都有一个一维的虚函数表叫做虚表,类的对象有一个指向虚表开始的虚指针。虚表是和类对应的,虚表指针是和对象对应的。
3:多态性是一个接口多种实现,是面向对象的核心,分为类的多态性和函数的多态性。
4:多态用虚函数来实现,结合动态绑定.
5:纯虚函数是虚函数再加上 = 0;
6:抽象类是指包括至少一个纯虚函数的类。
多态与非多态的实质区别就是函数地址是早绑定还是晚绑定。如果函数的调用,在编译器编译期间就可以确定函数的调用地址,并生产代码,是静态的,就是说地址是早绑定的。而如果函数调用的地址不能在编译器期间确定,需要在运行时才确定,这就属于晚绑定。
那么多态的作用是什么呢,封装可以使得代码模块化,继承可以扩展已存在的代码,他们的目的都是为了代码重用。而多态的目的则是为了接口重用。也就是说,不论传递过来的究竟是那个类的对象,函数都能够通过同一个接口调用到适应各自对象的实现方法。