您好,欢迎访问三七文档
1第四章继承性(Inheritance)继承是面向对象程序设计的重要特点之一,继承能提高软件的重用性。通过本章的学习,要求掌握以下内容:1、能通过继承已有的类建立新类;2、掌握派生类和基类的概念;3、掌握继承的三种方式:公有继承、保护继承、私有继承;4、掌握派生类的构造函数和析构函数;5、理解多重继承和虚继承。2本章编排•4.1继承与派生的概念•4.2派生类的定义及其继承方式•4.3派生类对象的初始化•4.4多重继承•4.5赋值兼容性3计算各类人员的工资经理姓名编号工龄固定工资总工资获得属性值计算总工资显示信息销售员姓名编号工龄销售额总工资获得属性值计算总工资显示信息工人姓名编号工龄固定工资工时总工资获得属性值计算总工资显示信息销售经理姓名编号工龄固定工资销售额总工资获得属性值计算总工资显示信息职员姓名编号工龄总工资获得属性值计算总工资显示信息公有性质类4.1继承与派生的概念4继承与派生的概念经理固定工资获得属性值计算总工资销售员销售额获得属性值计算总工资工人固定工资工时获得属性值计算总工资销售经理固定工资销售额获得属性值计算总工资职员姓名编号工龄总工资获得属性值计算总工资显示信息基类(父类)派生类派生类(子类)5继承与派生的概念•继承:新类具有基类中已有属性和方法•派生:在基类基础上加上满足新类特定要求所需的新成员•基类称为父类,子类称为派生类;64.2派生类的定义•格式:class派生类名:[继承方式]基类名{派生类新定义};其中继承方式有:publicprivateprotected继承方式的不同,确定了基类的成员在派生类中的访问控制权限。默认继承方式为private。7派生类的定义例:如果A是基类,B是A的派生类,那么B将继承A的数据和函数。classA{public:voidFunc1(void);voidFunc2(void);};classB:publicA{public:voidFunc3(void);voidFunc4(void);};voidmain(){Bb;b.Func1();b.Func2();b.Func3();b.Func4();}8派生类的定义•基类中的成员函数可以访问基类的所有成员,但不能访问派生类的成员•基类的对象只能访问基类的公有数据成员和调用基类的公有成员函数,基类对象不能访问派生类的成员•派生类中的成员函数可以访问派生类的所有成员,也能访问其基类的public成员和protect成员•派生类的对象能访问派生类的公有数据成员和调用派生类的公有成员函数,公有继承的派生类对象还能够访问其基类的public成员和protect成员9派生类的定义•C++的“继承”特性可以提高程序的可复用性。•要防止乱用“继承”:1、如果类A和类B毫不相关,不可以为了使B的功能更多些而让B继承A的功能。2、如果类B有必要使用A的功能,则要分两种情况考虑:(1)若在逻辑上B是A的“一种”(akindof),则允许B继承A的功能。(2)若在逻辑上A是B的“一部分”(apartof),则不允许B继承A的功能,而是要用A和其它东西组合出B。10派生类的定义例1:定义职员和工人类:classemployee{protected:charName[30];charNum[5];intWork_Age;floatTotal_Salary;public:voidGet_Message();voidPay();voidShow_Message();};classworker:publicemployee{floatSalary;intWork_Hour;public:worker(){};voidGet_Message();voidPay();~Worker(){};};11继承的好处•复用编好的代码和设计好的数据结构,而不用重复编写(软件重用和接口重用);•使程序易于维护,因为相关的数据和代码集中放在某处;•有效模拟了实际生活中的许多关系,如人与男人,交通工具和汽车等。12继承方式基类中成员在派生类中的访问权限记忆:基类私有成员不可访问;公有继承不变,私有继承私有,保护继承保护。继承方式基类特性派生类特性派生类中的成员函数派生类的对象公有继承publicprotectedprivatepublicprotected不可访问可访问基类中的公有成员和保护成员可访问基类和派生类中的公有成员私有继承publicprotectedprivateprivateprivate不可访问可访问基类中的公有成员和保护成员不能访问基类中的所有成员保护继承publicprotectedprivateprotectedprotected不可访问可访问基类中的公有成员和保护成员不能访问基类中的所有成员13继承方式例:说明下列程序中哪些语句是错误的。classBase{public:inta1;protected:inta2;private:inta3;};classB1:publicBase{public:voidf1(){a1=1;a2=2;a3=3;}};classB11:publicB1{public:voidf1(){a1=1;a2=2;a3=3;}};14继承方式ClassBase{public:inta1;protected:inta2;private:inta3;};ClassB3:protectedBase{public:voidf3(){a1=1;a2=2;a3=3;}};classB33:publicB3{public:voidf3(){a1=1;a2=2;a3=3;}};覆盖与继承154.3派生类对象的初始化•定义了一个派生类后,它将继承其基类中的全部成员。则派生类对象中不仅包含派生类的数据成员,还包含从父类继承的全部数据成员。•派生类对象初始化时,既要对派生类本身的数据成员初始化,又要对基类继承来的数据成员初始化。•C++语言定义派生类构造函数的格式为:派生类名(变量表):父类名(变量表),对象成员名(变量表);在冒号“:”后面是父类构造函数表(原则上有多少个父类就有多少个父类构造函数),以及对象成员初始化列表。16例2:例1中职员和工人类的构造函数•基类——职员类构造函数employee(char*n,char*no,intt,floatts){strcpy(Name,n);strcpy(Nume,no);Work_Age=t;Total_Salary=ts;}•派生类——工人类构造函数worker(char*n,char*no,intt,floatts,floats,inth):employee(n,no,t,ts){Salary=s;Work_Hour=h;}4.3派生类对象的初始化(续)17(1)当使用基类参数的构造函数来完成基类成员的初始化时,即使派生类构造函数本身无需完成任何工作(函数体为空),也必须定义派生类的构造函数。(2)如果基类定义有缺省构造函数,则在派生类构造函数可省略基类初始列表(3)派生类构造函数的执行顺序是:先父母(执行基类构造函数),再客人(初始化对象成员),最后自己(初始化派生类本身的普通数据成员)。(4)派生类析构函数的执行顺序与派生类构造函数的执行顺序刚好相反184.4多重继承一、多重继承的概念及定义二、多重继承下的初始化(多重继承派生类的构造函数)三、二义性及解决方法(作用域限制符和虚基类)四、赋值兼容规则194.4.1多重继承的概念•多重继承:派生类有多个直接基类,如:•派生类与每个基类之间的关系仍可看作是一个单继承输入设备输出设备输入/出设备20多重继承的定义•多继承下派生类的定义格式如下:class派生类名:继承方式1基类名1,继承方式2基类名2,......{派生类新定义的成员};•多个基类名间用逗号隔开,继承方式同单继承。21多重继承的概念及定义例3:工资例子经理固定工资获得属性值计算总工资销售员销售额获得属性值计算总工资工人固定工资工时获得属性值计算总工资销售经理固定工资销售额获得属性值计算总工资职员姓名编号工龄总工资获得属性值计算总工资显示信息22多重继承的概念及定义classManager{classSell{protected:protected:floatSalary;floatSale;public:public:Manager(float);Sell(float);floatGet_Salary();floatGet_Sale();};};classSell_Manager:publicManager,publicSell{public:Sell_Manager(float,float);};234.4.2多继承的初始化•多继承下派生类的构造函数成员初始化列表中应包含所有基类的构造函数,其定义格式:派生类构造函数名(参数表):基类名1(参数表1),基类名2(参数表2,…,对象成员名(参数表n)•多重继承派生类构造函数的执行顺序(析构函数相反):所有基类的构造函数(基类间以定义派生类时顺序为准)对象成员的构造函数派生类的构造函数24多继承的初始化例4:例3中的构造函数•经理类的构造函数Manager(floatsa){Salary=sa;}•销售员类的构造函数Sell(floatse){Sale=se;}•销售经理类的构造函数Sell_Manager(floatsa,floatse):Manager(sa),Sell(se){}254.4.3多重继承的二义性•二义性:无法确定性、不唯一性•多重继承中可能出现的两种二义性:同名引起的二义性公共基类带来的二义性(重复继承)•解决二义性方法:作用域运算符::,虚基类26当多重继承的派生类的不同父类中含有同名成员时,这些成员都会被派生类所继承,派生类在使用这些成员,就会产生二义性。classX{protected:inta;public:voidmake(inti){a=i;}};classY{protected:inta;public:voidmake(inti){a=i;}};classZ:publicX,publicY{public:intmake(){returna;}//二义性};voidmain(){Zzobj;zobj.make(10);//二义性coutzobj.make()endl;}classZ:publicX,publicY{public:intmake(){returnX::a*Y::a;}};voidmain(){Zzobj;zobj.X::make(10);zobj.Y::make(20);coutzobj.make()endl;}27重复继承(RepeatedInheritance)•一个派生类多次间接继承同一个基类。经理固定工资获得属性值计算总工资销售员销售额获得属性值计算总工资工人固定工资工时获得属性值计算总工资销售经理固定工资销售额获得属性值计算总工资职员姓名编号工龄总工资获得属性值计算总工资28公共基类带来的二义性由于类“职员”两次成为类“销售经理”的间接基类,派生类“销售”继承到公共基类“职员”的两组数据成员,造成二义性问题。为了消除因公共基类而引出的二义性问题,同样可以使用“基类名::”来限定有二义性的成员名。常用的方法:虚基类虚基类使派生类从公共基类只继承一个数据成员,即从不同路径继承过来的同名数据成员和成员函数在内存中只有一个拷贝。294.4.4例5:职员、经理、销售员和销售经理的C++描述:classEmployee{protected:charName[30];charNum[5];intWork_Age;floatTotal_Salary;public:Employee(char*,char*,int,float);voidGet_Message();voidPay();};classManager:virtualpublicEmployee{protected:floatSalar
本文标题:OOP_4继承性
链接地址:https://www.777doc.com/doc-3608735 .html