1、2023-11-121 11234继承与派生的概念继承与派生的概念第第4章章 继承与派生继承与派生本章学习要点本章学习要点派生类的构成派生类的构成派生类的声明派生类的声明派生类中基类成员的访问属性派生类中基类成员的访问属性5派生类的构造函数和析构函数派生类的构造函数和析构函数2023-11-122 2698第第4章章 继承与派生继承与派生本章学习要点本章学习要点多重继承多重继承合成复制控制与继承合成复制控制与继承“继承继承”的构造函数的构造函数7派生类的复制控制成员派生类的复制控制成员2023-11-123 31211第第4章章 继承与派生继承与派生本章学习要点本章学习要点图书馆图书借阅管理系
2、统中图书馆图书借阅管理系统中继承与聚合的应用继承与聚合的应用聚合与组合聚合与组合10基类与派生类对象的关系基类与派生类对象的关系2023-11-124 4本章学习目标本章学习目标1.理解继承和派生的概念;2.掌握派生类的声明方式,派生类的构成;3.掌握三种不同继承方式对基类成员、派生类成员访问权限的影响;3.掌握派生类的构造函数的定义与执行;4.掌握派生类的复制控制成员的定义;4.掌握多重继承的声明方法;多重继承派生类的 构造函数与析构函数的定义及执行;5.理解虚基类的概念,掌握其作用和声明方法;6.理解组合的概念,掌握继承与派生在软件开发中 的意义。第第4章章 继承与派生继承与派生2023-
3、11-125 5现实世界中的例子现实世界中的例子几何形状几何形状矩形矩形圆圆汽车汽车工具车工具车轿车轿车面包车面包车旅行车旅行车 卡车卡车交通工具交通工具小汽车小汽车飞机飞机船船2023-11-126 6现实世界中的例子现实世界中的例子猴子猴子鸟鸟猫科猫科动物动物狮子狮子猎豹猎豹虎虎销售经理销售经理经理经理工人工人销售人员销售人员职员职员2023-11-127 7v面向对象技术强调软件的可重用性面向对象技术强调软件的可重用性(software reusability)。C+语言提供了类的继承机制,语言提供了类的继承机制,解决了软件重用问题。解决了软件重用问题。第第4章章 继承与派生继承与派生v
4、通过继承机制,可以方便地利用一个已有的类建通过继承机制,可以方便地利用一个已有的类建立新类,重用已有软件中的部分甚至很大的部分。立新类,重用已有软件中的部分甚至很大的部分。v微软基础类微软基础类MFC,就是通过类的继承来体现类的,就是通过类的继承来体现类的可重用性和可扩充性。可重用性和可扩充性。2023-11-128 8v在在C+中,所谓中,所谓“继承继承”就是在一个或多就是在一个或多个已存在的类的基础上建立一个新的类。个已存在的类的基础上建立一个新的类。已存在的类称为已存在的类称为“基类基类”、“父类父类”或或“一般类一般类”。新建立的类称为。新建立的类称为“派生类派生类”、“子类子类”或或
5、“特殊类特殊类”。4.1 继承与派生的概念继承与派生的概念第第4章章 继承与派生继承与派生2023-11-129 9v一个新类从已有的类那里获得其已有特性,这种一个新类从已有的类那里获得其已有特性,这种现象称为现象称为类的继承类的继承。通过继承,一个新建子类从。通过继承,一个新建子类从已有的父类那里获得父类的特性。已有的父类那里获得父类的特性。v从另一角度说,从已有的父类产生一个新的子类,从另一角度说,从已有的父类产生一个新的子类,称为称为类的派生类的派生。类的继承是用已有的类来建立专。类的继承是用已有的类来建立专用类的编程技术。用类的编程技术。4.1 继承与派生的概念继承与派生的概念第第4章
6、章 继承与派生继承与派生2023-11-121010v派生类派生类继承继承了基类的所有数据成员和成员函数(不了基类的所有数据成员和成员函数(不包括基类的构造函数和析构函数),并可以包括基类的构造函数和析构函数),并可以增加增加自自己的新成员,同时也可以己的新成员,同时也可以调整调整来自基类的数据成员来自基类的数据成员和成员函数。和成员函数。v基类和派生类是相对而言的。基类和派生类是相对而言的。一个基类可以派生出一个基类可以派生出多个派生类,每一个派生类又可以作为基类再派生多个派生类,每一个派生类又可以作为基类再派生出新的派生类。一代一代地派生下去,就形成了类出新的派生类。一代一代地派生下去,就
7、形成了类的继承层次结构。的继承层次结构。4.1 继承与派生的概念继承与派生的概念第第4章章 继承与派生继承与派生2023-11-121111图图4-1 4-1 单继承单继承中学生中学生学生学生初中生初中生高中生高中生专科生专科生本科生本科生研究生研究生 硕士生硕士生博士生博士生大学生大学生小学生小学生留学生留学生一个派生类只从一个基类派生,这称为单继承一个派生类只从一个基类派生,这称为单继承(single(single inheritance)inheritance),这种继承关系所形成的层次是一个树这种继承关系所形成的层次是一个树形结构,可以用图形结构,可以用图4-14-1表示。表示。第第4
8、章章 继承与派生继承与派生2023-11-121212图图4-2 4-2 多继承多继承销售经理销售经理经理经理工人工人销售人员销售人员职员职员一个派生类不仅可以从一个基类派生,也可以从多个一个派生类不仅可以从一个基类派生,也可以从多个基类派生。基类派生。一个派生类有两个或多个基类的称为多重一个派生类有两个或多个基类的称为多重继承继承(multiple inheritance),这种继承关系所形成的这种继承关系所形成的结构如图结构如图4-2所示。所示。第第4章章 继承与派生继承与派生2023-11-121313v基类和派生类的关系,可以表述为:基类和派生类的关系,可以表述为:派生类是基类的具体化
9、,而基类是派生类的抽象。派生类是基类的具体化,而基类是派生类的抽象。4.1 继承与派生的概念继承与派生的概念第第4章章 继承与派生继承与派生2023-11-121414v单继承派生类的声明格式如下:单继承派生类的声明格式如下:class 派生类名派生类名:继承方式继承方式 基类名基类名 派生类新增加的成员派生类新增加的成员 ;4.2 派生类的声明方式派生类的声明方式第第4章章 继承与派生继承与派生 继承方式可以是继承方式可以是public(公用的公用的)、private(私有私有的的)、protected(受保护的受保护的)。此项是可选的,如。此项是可选的,如果不写此项,则默认为果不写此项,则
10、默认为private(私有的私有的)。2023-11-121515第第4章章 继承与派生继承与派生class Circle /声明基类Circle圆类public:/Circle类公用成员函数 void setRadious(int r)radious=r;int getRadious()return radious;void showRadious()coutBase class Circle:radious=radious endl;private:/Circle类私有数据成员 int radious;/圆半径;2023-11-121616/以public方式声明派生类 Cylinder圆
11、柱体类class Cylinder:public Circle public:/Cylinder类公用成员函数 void setHeight(int h)height=h;int getHeight()return height;void showHeight()cout Derived class Cylinder:height=height endl;private:/Cylinder类私有数据成员 int height;/圆柱体高度;第第4章章 继承与派生继承与派生2023-11-121717v有时候我们会定义这样一种类:不希望其他类继有时候我们会定义这样一种类:不希望其他类继承它,或者
12、不想考虑它是否适合作为一个基类,承它,或者不想考虑它是否适合作为一个基类,为了实现这一目的,为了实现这一目的,C+11提供了一种防止继承提供了一种防止继承发生的方法,即在类名后跟一个标识符发生的方法,即在类名后跟一个标识符final。/NoDerived不能作为基类不能作为基类 class NoDerived final/*/;/错误:错误:NoDerived是是final的的 class Error:NoDerived/*/4.1 继承与派生的概念继承与派生的概念第第4章章 继承与派生继承与派生2023-11-121818class Base/*/;/Last不能作为基类不能作为基类clas
13、s Last final:Base/*/错误:错误:Last是是final的的class Error2:Last/*/4.1 继承与派生的概念继承与派生的概念第第4章章 继承与派生继承与派生还能把类中某个成员函数指定为还能把类中某个成员函数指定为final,则派生,则派生类中任何尝试重写该函数的操作都将引发编译类中任何尝试重写该函数的操作都将引发编译错误。详见错误。详见5.5节。节。2023-11-121919v派生类中的成员派生类中的成员包括包括从基类继承过来的成员从基类继承过来的成员和和自己自己新增加的成员新增加的成员两大部分,从基类继承过来的成员体两大部分,从基类继承过来的成员体现了派生
14、类从基类继承而获得的共性,而新增加的现了派生类从基类继承而获得的共性,而新增加的成员体现了派生类的个性,体现了派生类与基类的成员体现了派生类的个性,体现了派生类与基类的不同,体现了不同派生类的区别。不同,体现了不同派生类的区别。4.3 派生类的派生类的构成构成第第4章章 继承与派生继承与派生2023-11-122020第第4章章 继承与派生继承与派生图图4-3 4-3 基类基类CircleCircle及其派生类及其派生类CylinderCylinder的成员示意图的成员示意图2023-11-122121v实际上,并不是把基类的成员和派生类自己新增加实际上,并不是把基类的成员和派生类自己新增加的
15、成员简单地加在一起就成为派生类。构造一个派的成员简单地加在一起就成为派生类。构造一个派生类一般经历生类一般经历3个步骤:个步骤:1.从基类接收成员从基类接收成员 2.调整从基类接收的成员调整从基类接收的成员 3.增加新成员增加新成员4.3 派生类的派生类的构成构成第第4章章 继承与派生继承与派生2023-11-1222221.从基类接收成员从基类接收成员派生类要接收基类全部的成员(但不包括基类的构造派生类要接收基类全部的成员(但不包括基类的构造函数、析构函数),也就是说是没有选择的,不能选函数、析构函数),也就是说是没有选择的,不能选择接收其中一部分成员,而舍弃另一部分成员。择接收其中一部分成
16、员,而舍弃另一部分成员。4.3 派生类的派生类的构成构成第第4章章 继承与派生继承与派生2023-11-1223232.调整从基类接收的成员调整从基类接收的成员调整包括二个方面:调整包括二个方面:一方面,可以改变基类成员在派生类中的访问属性,这是通过一方面,可以改变基类成员在派生类中的访问属性,这是通过指定继承方式来实现的,如果在声明派生类时指定继承方式为指定继承方式来实现的,如果在声明派生类时指定继承方式为私有的,则基类中的公用成员和保护成员在派生类中的访问属私有的,则基类中的公用成员和保护成员在派生类中的访问属性就成了私有的,在派生类外不能访问;通过在类内使用性就成了私有的,在派生类外不能
17、访问;通过在类内使用using声明语句,可进一步改变继承方式作用下的基类成员在声明语句,可进一步改变继承方式作用下的基类成员在派生类中的访问属性。派生类中的访问属性。4.3 派生类的派生类的构成构成第第4章章 继承与派生继承与派生2023-11-1224242.调整从基类接收的成员调整从基类接收的成员调整包括二个方面:调整包括二个方面:另一方面,可以在派生类中声明一个与基类成员同名的成员,另一方面,可以在派生类中声明一个与基类成员同名的成员,则派生类的新成员会屏蔽与其同名的基类成员,使同名的基类则派生类的新成员会屏蔽与其同名的基类成员,使同名的基类成员成为成员成为“不可见不可见”的,即基类成员
18、的名字被隐藏。的,即基类成员的名字被隐藏。关于基类成员在派生类中的访问属性问题和名字隐藏问题,稍关于基类成员在派生类中的访问属性问题和名字隐藏问题,稍后会作详细介绍。后会作详细介绍。4.3 派生类的派生类的构成构成第第4章章 继承与派生继承与派生2023-11-1225253.增加新成员增加新成员这部分内容是很重要的,它体现了派生类对基类功能这部分内容是很重要的,它体现了派生类对基类功能的扩展。程序员要根据实际情况的需要,仔细考虑应的扩展。程序员要根据实际情况的需要,仔细考虑应该给派生类增加哪些数据成员和成员函数。该给派生类增加哪些数据成员和成员函数。4.3 派生类的派生类的构成构成第第4章章
19、 继承与派生继承与派生2023-11-122626v派生类中基类成员的访问属性派生类中基类成员的访问属性不仅不仅与在声明基与在声明基类时所声明的访问属性有关,类时所声明的访问属性有关,而且而且与在声明派与在声明派生类时所指定的对基类的继承方式生类时所指定的对基类的继承方式,以及以及类内类内using声明语句的使用情况声明语句的使用情况有关有关,这些因素共,这些因素共同决定基类成员在派生类中的访问属性。同决定基类成员在派生类中的访问属性。4.4 派生类中基类成员的访问属性派生类中基类成员的访问属性第第4章章 继承与派生继承与派生2023-11-122727v派生类对基类的继承方式有派生类对基类的
20、继承方式有public,private和和protected 3种。不同的继承方式决定了基类成员在种。不同的继承方式决定了基类成员在派生类中的访问属性。派生类中的访问属性。(1)公用继承公用继承(public inheritance)基类的公用成员和保护成员在派生类中保持原有访基类的公用成员和保护成员在派生类中保持原有访问属性,其私有成员仍为基类私有。问属性,其私有成员仍为基类私有。4.4 派生类中基类成员的访问属性派生类中基类成员的访问属性第第4章章 继承与派生继承与派生2023-11-122828(2)私有继承私有继承(private inheritance)基类的公用成员和保护成员在派生
21、类中成了私有成员。基类的公用成员和保护成员在派生类中成了私有成员。其私有成员仍为基类私有。其私有成员仍为基类私有。4.4 派生类中基类成员的访问属性派生类中基类成员的访问属性第第4章章 继承与派生继承与派生2023-11-122929(3)受保护的继承受保护的继承(protected inheritance)基类的公用成员和保护成员在派生类中成了保护成员,基类的公用成员和保护成员在派生类中成了保护成员,其私有成员仍为基类私有。其私有成员仍为基类私有。保护成员的意思是保护成员的意思是:不能被外界访问,但可以被派生不能被外界访问,但可以被派生类的成员访问。类的成员访问。4.4 派生类中基类成员的访
22、问属性派生类中基类成员的访问属性第第4章章 继承与派生继承与派生2023-11-123030v在在声明声明一个派生类时将基类的继承方式指定为一个派生类时将基类的继承方式指定为public的,称为的,称为公用继承公用继承。v用公用继承方式建立的派生类称为用公用继承方式建立的派生类称为公用派生类公用派生类(public derived class),其基类称为,其基类称为公用基类公用基类(public base class)。4.4.1 公用继承公用继承第第4章章 继承与派生继承与派生2023-11-1231314.4.1 公用继承公用继承第第4章章 继承与派生继承与派生表表4-1 4-1 公用基
23、类成员在派生类中的访问属性公用基类成员在派生类中的访问属性公用基类的成员公用基类的成员在公用派生类中的访问属性在公用派生类中的访问属性私有成员不可访问公用成员公用保护成员保护2023-11-123232第第4章章 继承与派生继承与派生【例例4-1】公用继承的例子。公用继承的例子。#include using namespace std;class Circle /声明基类Circle圆类public:/Circle类公用成员函数 void setRadius(int r)radius=r;int getRadius()return radius;void showRadius()cout Ba
24、se class Circle:radius=radius endl;private:/Circle类私有数据成员 int radius;/圆半径;2023-11-12燕京理工学院3333/以public方式声明公用派生类Cylinder圆柱体类class Cylinder:public Circle public:/Cylinder类公用成员函数 void setHeight(int h)height=h;int getHeight()return height;void showHeight()cout Derived class Cylinder:height=height endl;v
25、oid set(int r,int h)/radius=r;setRadius(r);height=h;第第4章章 继承与派生继承与派生2023-11-123434 void show()/cout radius=radius endl;cout radius=getRadius()endl;/showRadius();/该语句与上句作用相同 cout height=height endl;private:/Cylinder类私有数据成员 int height;/圆柱体高度;第第4章章 继承与派生继承与派生2023-11-123535int main()Cylinder obj;obj.set
26、Radius(10);obj.showRadius();obj.setHeight(20);obj.showHeight();obj.set(30,40);obj.show();return 0;第第4章章 继承与派生继承与派生程序运行结果如下:程序运行结果如下:Base class Circle:radius=10Base class Circle:radius=10Derived class Cylinder:height=20Derived class Cylinder:height=20radius=30radius=30height=40height=402023-11-123636
27、v在声明一个派生类时将基类的继承方式指定为在声明一个派生类时将基类的继承方式指定为private的,称为的,称为私有继承私有继承。v用私有继承方式建立的派生类称为用私有继承方式建立的派生类称为私有派生类私有派生类(private derived class),其基类称为,其基类称为私有基类私有基类(private base class)。4.4.2 私有继承私有继承第第4章章 继承与派生继承与派生2023-11-1237374.4.2 私有继承私有继承第第4章章 继承与派生继承与派生表表4-2 4-2 私有基类成员在派生类中的访问属性私有基类成员在派生类中的访问属性私有基类的成员私有基类的成员
28、在私有派生类中的访问属性在私有派生类中的访问属性私有成员不可访问公用成员私有保护成员私有2023-11-123838第第4章章 继承与派生继承与派生【例例4-24-2】将将【例例4-14-1】中的公用继承方式改为中的公用继承方式改为 用私有继承方式用私有继承方式(基类基类BaseBase不变不变)。私有派生类如下私有派生类如下:/以private方式声明派生类Cyclinder class Cylinder:private Circlepublic:/Cylinder类公用成员函数 void setHeight(int h)height=h;int getHeight()return heig
29、ht;void showHeight()cout Derived class Cylinder:height=height endl;void set(int r,int h)setRadius(r);height=h;void show()cout radius=getRadius()endl;cout height=height endl;private:/Cylinder类私有数据成员 int height;/圆柱体高度;2023-11-123939int main()Cylinder obj;/obj.setRadius(10);/obj.showRadius();obj.setHei
30、ght(20);obj.showHeight();obj.set(30,40);obj.show();return 0;第第4章章 继承与派生继承与派生2023-11-124040v由由protected声明的成员称为声明的成员称为“受保护的成员受保护的成员”,简,简称称“保护成员保护成员”。从类的用户角度来看,保护成员等。从类的用户角度来看,保护成员等价于私有成员。但有一点与私有成员不同,保护成员价于私有成员。但有一点与私有成员不同,保护成员可以被派生类的成员函数访问。可以被派生类的成员函数访问。4.4.3 保护成员和保护继承保护成员和保护继承第第4章章 继承与派生继承与派生2023-11-
31、12燕京理工学院4141v在定义一个派生类时将基类的继承方式指定为在定义一个派生类时将基类的继承方式指定为protected的,称为的,称为保护继承保护继承。v用保护继承方式建立的派生类称为用保护继承方式建立的派生类称为保护派生类保护派生类(protected derived class),其基类称为受保护的基,其基类称为受保护的基类类(protected base class),简称,简称保护基类保护基类。4.4.3 保护成员和保护继承保护成员和保护继承第第4章章 继承与派生继承与派生2023-11-124242第第4章章 继承与派生继承与派生表4-3 基类成员在派生类中的访问属性4.4.3
32、 保护成员和保护继承保护成员和保护继承基类中的基类中的成员成员在在公用派生类公用派生类中的访问属性中的访问属性在在私有派生类私有派生类中的访问属性中的访问属性在在保护派生类保护派生类中的访问属性中的访问属性私有成员不可访问不可访问不可访问公用成员公用私有保护保护成员保护私有保护2023-11-124343通过以上的介绍,可以知道:通过以上的介绍,可以知道:(1)在派生类中,成员有)在派生类中,成员有4种不同的访问属性:种不同的访问属性:公用的公用的:派生类内和派生类外都可以访问。:派生类内和派生类外都可以访问。受保护的受保护的:派生类内可以访问,派生类外不能访问,:派生类内可以访问,派生类外不
33、能访问,其下一层的派生类可以访问。其下一层的派生类可以访问。私有的私有的:派生类内可以访问,派生类外不能访问。:派生类内可以访问,派生类外不能访问。不可访问的不可访问的:派生类内和派生类外都不能访问。:派生类内和派生类外都不能访问。4.4.3 保护成员和保护继承保护成员和保护继承第第4章章 继承与派生继承与派生2023-11-124444第第4章章 继承与派生继承与派生表表4-44-4派生类中的成员的访问属性派生类中的成员的访问属性派生类中的成员派生类中的成员在派生类在派生类中中在派生类在派生类外外在下层公用派在下层公用派生类中生类中派生类中访问属性为公用的成员可以可以可以派生类中访问属性为受
34、保护的成员可以不可以可以派生类中访问属性为私有的成员可以不可以不可以在派生类中不可访问的成员不可以不可以不可以2023-11-124545(2)类的成员在不同作用域中有不同的访问属性类的成员在不同作用域中有不同的访问属性,对,对这一点要十分清楚。这一点要十分清楚。在学习过派生类之后,再讨论一个类的某成员的访问属在学习过派生类之后,再讨论一个类的某成员的访问属性,一定要指明是在哪一个作用域中。如基类性,一定要指明是在哪一个作用域中。如基类Circle的的成员函数成员函数setRadius,它在基类中的访问属性是公用的,它在基类中的访问属性是公用的,在私有派生类在私有派生类Cylinder中的访问
35、属性是私有的。中的访问属性是私有的。4.4.3 保护成员和保护继承保护成员和保护继承第第4章章 继承与派生继承与派生2023-11-12燕京理工学院4646第第4章章 继承与派生继承与派生【例例4-34-3】保护继承的例子。保护继承的例子。/以private方式声明派生类Cyclinder class Cylinder:protected Circlepublic:/Cylinder类公用成员函数 void setHeight(int h)height=h;int getHeight()return height;void showHeight()cout Derived class Cyli
36、nder:height=height endl;void set(int r,int h)setRadius(r);height=h;void show()cout radius=getRadius()endl;cout height=height endl;private:/Cylinder类私有数据成员 int height;/圆柱体高度;2023-11-124747int main()Cylinder obj;/obj.setRadius(10);/obj.showRadius();obj.setHeight(20);obj.showHeight();obj.set(30,40);obj
37、.show();return 0;第第4章章 继承与派生继承与派生2023-11-124848v有时我们需要改变派生类继承的基类某个成员的可访有时我们需要改变派生类继承的基类某个成员的可访问性,通过使用问性,通过使用using声明可以达到这一目的。声明可以达到这一目的。第第4章章 继承与派生继承与派生class Basepublic:size_t size()const return n;protected:size_t n;/注意:注意:private继承继承class Derived:private Basepublic:using Base:size;protected:using Ba
38、se:n;2023-11-124949v在前面介绍派生类的构成时曾提到:可以在派生类在前面介绍派生类的构成时曾提到:可以在派生类中声明一个与基类成员同名的成员,则派生类的新中声明一个与基类成员同名的成员,则派生类的新成员会屏蔽与其同名的基类成员,使同名的基类成成员会屏蔽与其同名的基类成员,使同名的基类成员成为员成为“不可见不可见”的,即基类成员的名字被隐藏。的,即基类成员的名字被隐藏。4.4.4 成员成员同同名名问题问题第第4章章 继承与派生继承与派生2023-11-12燕京理工学院5050第第4章章 继承与派生继承与派生【例例4-44-4】派生类成员函数与基类成员函数同名。派生类成员函数与基
39、类成员函数同名。#include using namespace std;class Circle /声明基类Circlepublic:/基类公用成员 void set(int r)radius=r;void show()cout Base class Circle:radius=radius endl;private:/基类Circle的私有数据成员 int radius;/圆半径;2023-11-125151第第4章章 继承与派生继承与派生/以public方式声明派生类Cylinderclass Cylinder:public Circlepublic:void set(int r,int
40、 h)Circle:set(r);height=h;void show()Circle:show();cout Derived class Cylinder:height=height endl;private:int height;/圆柱体高度;2023-11-125252 int main()Cylinder obj;obj.set(10,20);/L3 obj.show();/L4 /obj.set(10);/L5错误 obj.Circle:set(30);/L6正确 obj.Circle:show();/L7 return 0;第第4章章 继承与派生继承与派生程序运行结果如下:程序运行
41、结果如下:Base class Circle:radius=10Base class Circle:radius=10Derived class Cylinder:height=20Derived class Cylinder:height=20Base class Circle:radius=30Base class Circle:radius=302023-11-125353从上例可以看出:从上例可以看出:v(1)如果是在派生类中声明了一个与基类成员函)如果是在派生类中声明了一个与基类成员函数名字相同,参数也相同的成员函数,则基类中的数名字相同,参数也相同的成员函数,则基类中的成员函数将被
42、隐藏。成员函数将被隐藏。v(2)如果是在派生类中声明了一个与基类成员函)如果是在派生类中声明了一个与基类成员函数名字相同,但参数不同的成员函数,则基类中的数名字相同,但参数不同的成员函数,则基类中的成员函数也将被隐藏。成员函数也将被隐藏。4.4.4 成员成员同同名名问题问题第第4章章 继承与派生继承与派生2023-11-125454第第4章章 继承与派生继承与派生补充补充:派生类重定义基类数据成员的例子。派生类重定义基类数据成员的例子。#include using namespace std;class Base /声明基类public:/基类公用成员 float y;void set(int
43、 n)x=n;void show()coutBase class:x=x endl;private:/基类私有成员 int x;2023-11-125555第第4章章 继承与派生继承与派生/以public方式声明派生类Derived class Derived:public Basepublic:void set(int i,int j,int k)Base:set(i);y=j;z=k;void show()Base:show();coutBase class:y=Base:yendl;coutDerived class:y=yendl;coutDerived class:z=zendl;p
44、rivate:int y,z;2023-11-125656 int main()Derived obj;obj.set(1,2,3);obj.Base:y=12.3;obj.show();return 0;第第4章章 继承与派生继承与派生程序运行结果如下:程序运行结果如下:Base class:x=1Base class:x=1Base class:y=12.3Base class:y=12.3Derived class:y=2Derived class:y=2Derived class:z=3Derived class:z=32023-11-125757第第4章章 继承与派生继承与派生补充实
45、例补充实例 人员类(人员类(Person)及其子类雇员类()及其子类雇员类(Employee)的定义及使用。的定义及使用。2023-11-125858第第4章章 继承与派生继承与派生#includeusing namespace std;#includeclass Person /人员类定义protected:char m_strName10;/姓名 int m_nAge;/年龄 int m_nSex;/性别public:void register(char*name,int age,char sex)char*getName()/获取姓名int getAge()/获取年龄char getSe
46、x()/获取性别void showMe();2023-11-125959第第4章章 继承与派生继承与派生void Person:register(char*name,int age,char sex)strcpy(m_strName,name);m_nAge=age;m_nSex=(sex=m?0:1);char*Person:getName()/获取姓名return m_strName;int Person:getAge()/获取年龄return m_nAge;char Person:getSex()/获取性别return m_nSex=0?m:f;void Person:showMe()c
47、outGetName()tGetSex()t getAge()tendl;2023-11-126060第第4章章 继承与派生继承与派生class Employee:public Person /雇员类定义 char m_strDept20;/工作部门 float m_fSalary;/月薪public:Employee()EmployeeRegister(XXX,0,m,XXX,0);void EmployeeRegister(char*name,int age,char sex,char*dept,float salary);void showMe();2023-11-126161第第4章章
48、 继承与派生继承与派生void Employee:EmployeeRegister(char*name,int age,char sex,char*dept,float salary)register(name,age,sex);strcpy(m_strDept,dept);m_fSalary=salary;void Employee:showMe()/子类的成员函数可以调用基类的公有成员函数 coutgetName()tgetSex()tgetAge()t;/子类的成员函数也可以直接访问基类的保护类数据 /coutm_strName t m_nSext m_nAge t;coutm_strD
49、epttm_fSalaryendl;2023-11-126262第第4章章 继承与派生继承与派生int main()Employee emp;emp.showMe();emp.EmployeeRegister(张莉,40,f,图书馆,2000);emp.showMe();/*基类的ShowMe()在公有继承方式下相当于派生类的公有成员,在main()中可以显式访问基类成员*/emp.Person:showMe();cout调用基类 GetName()返回值:emp.getName()endl;return 0;2023-11-126363第第4章章 继承与派生继承与派生练习题练习题 定义一个基
50、类有姓名、性别、年龄,再由基类派生出定义一个基类有姓名、性别、年龄,再由基类派生出学生类和教师类,学生类增加学号、班级、专业和入学生类和教师类,学生类增加学号、班级、专业和入学成绩,教师类增加工号、职称和工资。每个类都有学成绩,教师类增加工号、职称和工资。每个类都有相关数据的输入和输出方法。相关数据的输入和输出方法。2023-11-12燕京理工学院6464第第4章章 继承与派生继承与派生#include#include#includeclass base /定义一个基类protected:char name20;/姓名 char sex3;/性别 int age;/年龄 ;class teac