
《c继承与派生》PPT课件.ppt
47页第八章第八章 继承与派生继承与派生2022/5/311派生类的引入派生类的引入C+的类提供了良好的的类提供了良好的模块分解模块分解技术,技术,也具有也具有可重用软件可重用软件所期望的品质:它们所期望的品质:它们是相似一致的模块,通过信息隐藏,将是相似一致的模块,通过信息隐藏,将它们的它们的接口和实现接口和实现清楚地分开来清楚地分开来我们还希望在类的基础上能取得更好的我们还希望在类的基础上能取得更好的可重用性和可扩充性可重用性和可扩充性的目标面向对象的面向对象的继承技术继承技术提供了实现上述目提供了实现上述目标的有力手段标的有力手段2022/5/312现实中的继承与派生现实中的继承与派生在在自自然然界界中中,继继承承这这个个概概念念是是非非常常普普遍遍的的例例如如:小小猫猫仔仔继继承承了了猫猫爸爸猫猫妈妈的的特特性性,所所以以长长的的是是猫猫鼻鼻子子猫猫眼眼,我我们不会把它错认为是小狗们不会把它错认为是小狗继继承承就就是是将将一一些些本本质质的的特特性性遗遗传传给给子子代代,使使后后代代在在很很大大程程度度上上具具有有与与父父代代相同的性质相同的性质子代同时还具有父代没有的特性子代同时还具有父代没有的特性。
2022/5/313再来看一个现实世界中的例子:再来看一个现实世界中的例子:Rectangle Square Diamond ParallelogramRectangle Square Diamond ParallelogramQuadrangleQuadrangle四四边边形形是是一一个个基基本本的的概概念念,矩矩形形、正正方方形形、菱菱形形和和平平行行四四边边形形都都是是派派生生的的概概念念,因因为为它它们们都都属属于于四四边边形形,它它们们继继承承了了四四边边形形的的所所有有性质,同时又扩充出各自的特性性质,同时又扩充出各自的特性2022/5/314从上面的例子可以看出从上面的例子可以看出:而而且且子子代代可可以以拥拥有有父父代代没没有有的的特特性性,这是这是可扩充的概念可扩充的概念一一旦旦指指定定了了某某种种事事物物父父代代的的本本质质特特征征,那那么么它它的的子子代代将将会会自自动动具具有有那那些些性性质质这这就就是是一一种种朴朴素素的的可可重重用用的概念的概念2022/5/315从软件设计的角度来看从软件设计的角度来看:基基于于已已有有的的类类,可可以以建建立立新新的的类类。
这这个个新新的的类类既既重重用用已已有有类类的的功功能能,又又扩展扩展了新的功能了新的功能类类是是某某类类事事物物共共同同特特性性的的体体现现,它它对外提供了特定的功能对外提供了特定的功能2022/5/316C+的继承关系的继承关系继承就是在一个已经存在的类的基础上建继承就是在一个已经存在的类的基础上建立另一个新的类立另一个新的类基类基类派生类派生类已存在的类称为已存在的类称为“基类基类”或或“父类父类”,新,新建立的类称为建立的类称为“派生类派生类”或或“子类子类”,如,如图所示:图所示:2022/5/317派生类的功能主要通过以下方式来体现:派生类的功能主要通过以下方式来体现:派生类的特性派生类的特性吸收基类成员吸收基类成员添加新成员添加新成员改造基类成员改造基类成员从从编编码码的的角角度度来来看看,派派生生类类从从基基类类中中以以较较低低的的代代价价换换来来了了较较大大的的灵灵活活性性一一旦旦产产生生了了可可靠靠的的基基类类,只只需需要要调调试试派派生生类类中中所所作作的的修修改改即即可可派派生生类类可可以以对对继继承承的属性进行扩展、限制或改变的属性进行扩展、限制或改变2022/5/318单继承和多继承单继承和多继承单继承:派生类只有一个直接基类单继承:派生类只有一个直接基类ABC单继承单继承XYZ多继承多继承多继承:派生类有多个直接基类多继承:派生类有多个直接基类2022/5/319单继承派生类单继承派生类定义单继承派生类的语法格式:定义单继承派生类的语法格式:class 派生类名派生类名 : 基类名基类名/派生类新添加的成员派生类新添加的成员;“继继承承方方式式”可可以以是是public、private、以及以及 protected。
虽虽然然继继承承了了基基类类的的所所有有成成员员,但但是是派派生生类类并并非非都都能能访访问问基基类类的的所所有有成成员员,继继承承方方式式会影响派生类对基类中各种成员的引用会影响派生类对基类中各种成员的引用2022/5/3110公有派生类公有派生类在在声声明明派派生生类类时时将将继继承承方方式式指指定定为为public时,该类称为公有派生类时,该类称为公有派生类 class 派生类名派生类名 : public 基类名基类名 /派生类新添加的成员派生类新添加的成员;2022/5/3111基类的成员在公有派生类中的引用权限基类的成员在公有派生类中的引用权限基类基类公有成员公有成员私有成员私有成员保护成员保护成员公有派生类公有派生类公有成员公有成员不可访问成员不可访问成员保护成员保护成员不可访问成员不可访问成员在类外不能被直接访问在类外不能被直接访问在派生类的类内不能被直接访问在派生类的类内不能被直接访问2022/5/3112举例:公有派生举例:公有派生class Baseint v1;public:int v2;Base(int a=0,int b=0) v1=a;v2=b;class Derived : public Baseint v3;public:int v4;Derived(int a=0,int b=0)v3=a;v4=b;void func() int sum1=v1+v2+v3+v4; int sum2=v2+v3+v4; ;void main( )Derived obj(5,6);obj.v2=8;/错误错误2022/5/3113私有派生类私有派生类在在声声明明派派生生类类时时将将继继承承方方式式指指定定为为private时,该类称为私有派生类。
时,该类称为私有派生类class 派生类名派生类名 : private 基类名基类名 /派生类新添加的成员派生类新添加的成员;2022/5/3114基类的成员在私有派生类中的引用权限基类的成员在私有派生类中的引用权限基类基类公有成员公有成员私有成员私有成员保护成员保护成员私有派生类私有派生类私有成员私有成员不可访问成员不可访问成员私有成员私有成员2022/5/3115举例:私有派生举例:私有派生class Baseint v1;public:int v2;Base(int a=0,int b=0) v1=a;v2=b;class Derived : private Baseint v3;public:int v4;Derived(int a=0,int b=0)v3=a;v4=b;void func() int sum1=v1+v2+v3+v4; int sum2=v2+v3+v4; ;void main( )Derived obj(5,6);obj.v2=8;/错误错误/错误错误2022/5/3116公有派生和私有派生的比较公有派生和私有派生的比较虽虽然然派派生生类类继继承承了了基基类类所所有有的的成成员员,但但是是基基类类的的私私有有成成员员对对于于派派生生类类来来说说是是不不可见可见的,因此不能被派生类所访问。
的,因此不能被派生类所访问基类基类公有成员公有成员私有成员私有成员保护成员保护成员公有派生类公有派生类公有成员公有成员不可访问成员不可访问成员保护成员保护成员私有派生类私有派生类私有成员私有成员不可访问成员不可访问成员私有成员私有成员2022/5/3117保护成员的引入保护成员的引入为为了了解解决决这这个个问问题题,C+专专门门设设置置了了保保护护成成员员,即即用用protected关关键键字字说说明的成员明的成员保护成员的特性:保护成员的特性:能够被基类和派生类所访问能够被基类和派生类所访问和私有成员一样,类外不能访问和私有成员一样,类外不能访问2022/5/3118举例:保护成员举例:保护成员class Baseprotected:int v1;public:int v2;Base(int a=0,int b=0) v1=a;v2=b;class Derived : public Baseint v3;public:int v4;Derived(int a=0,int b=0)v3=a;v4=b;void func() int sum1=v1+v2+v3+v4; int sum2=v2+v3+v4; ;void main( )Derived obj(5,6);obj.v1=8;/错误错误/正确正确2022/5/3119保护派生类保护派生类在在声声明明派派生生类类时时将将继继承承方方式式指指定定为为protected时,该类称为保护派生类:时,该类称为保护派生类:class 派生类名派生类名 : protected 基类名基类名 /派生类新添加的成员派生类新添加的成员;2022/5/3120基类的成员在保护派生类中的引用权限基类的成员在保护派生类中的引用权限基类基类公有成员公有成员私有成员私有成员保护成员保护成员保护派生类保护派生类保护成员保护成员不可访问成员不可访问成员保护成员保护成员2022/5/3121小结小结不不同同的的继继承承方方式式,子子类类对对基基类类中中的的成成员的访问权限如下表所示:员的访问权限如下表所示:基类基类公有成员公有成员私有成员私有成员保护成员保护成员公有派生类公有派生类 公有成员公有成员 不可访问成员不可访问成员保护成员保护成员保护派生类保护派生类 保护成员保护成员 不可访问成员不可访问成员保护成员保护成员私有派生类私有派生类 私有成员私有成员 不可访问成员不可访问成员私有成员私有成员2022/5/3122派生类与基类同名成员的访问方式派生类与基类同名成员的访问方式C+允允许许派派生生类类可可以以重重新新定定义义基基类类的的成成员员,此此时时称称派派生生类类的的成成员员覆覆盖盖了了基基类类的的同名成员。
同名成员如如果果在在派派生生类类中中,想想使使用用基基类类的的同同名名成成员员,则则可可以以显显式式地地使使用用类类名名+限限定定符符的的方式,如下所示:方式,如下所示: 基类名基类名:成员成员2022/5/3123举例举例class Baseprotected:int v1;public:int v2;Base(int a=0,int b=0) v1=a;v2=b;class Derived : public Baseint v2;public:int v3;Derived(int a=0,int b=0)v2=a;v3=b;void func()int sum1=v1+v2+v3; int sum2=v1+Base:v2+v3;void main( )Derived obj(5,6);obj.v2=8;/错误错误obj.Base:v2=9;/使用的是使用的是Derived中的中的v2/使用的是使用的是Base中的中的v22022/5/3124派生类对象的构造和析构派生类对象的构造和析构派生类对象数据成员的构成:派生类对象数据成员的构成:从基类继承过来的数据成员从基类继承过来的数据成员派生类自定义的数据成员派生类自定义的数据成员如何初始化这几部分数据成员呢?如何初始化这几部分数据成员呢?基本数据类型基本数据类型类类型类类型如何析构派生类对象?如何析构派生类对象?2022/5/3125单继承派生类的构造函数单继承派生类的构造函数派生类构造函数派生类构造函数(参数表参数表):基类构造函数基类构造函数(参数表参数表), 对象成员对象成员1(参数表参数表),对象成员对象成员n(参数表参数表),/初始化自定义数据成员初始化自定义数据成员如果基类使用的是缺省的构造函数或不带参如果基类使用的是缺省的构造函数。
