1第五章继承和派生类2继承性是面向对象程序设计中最重要的机制。这种机制提供了无限重复利用程序资源的一种途径。通过C++语言中的继承机制,可以扩充和完善旧的程序设计以适应新的需求。这样不仅可以节省程序开发的时间和资源,并且为未来程序增添了新的资源。5.1派生和继承的相关概念和作用3classStudent{intnum;charname[30];charsex;public:voiddisplay()//对成员函数display的定义{coutnum:numendl;coutname:nameendl;coutsex:sexendl;}};5.1派生和继承的相关概念和作用4classStudend1{intnum;//此行原来己有charname[20];//此行原来己有charsex;//此行原来己有intage;charaddr[20];public:voiddisplay();//此行原来己有{coutnum:numendl;//此行原来己有coutname:nameendl;//此行原来己有coutsex:sexendl;//此行原来己有coutage:ageendl;coutaddress:addrendl;}};5.1派生和继承的相关概念和作用5利用原来定义的类Student作为基础,再加上新的内容即可,以减少重复的工作量。C++提供的继承机制就是为了解决这个问题。在C++中所谓“继承”就是在一个已存在的类的基础上建立一个新的类。已存在的类称为“基类(baseclass)”或“父类(fatherclass)”。新建立的类称为“派生类(derivedclass)”或“子类(sonclass)”。5.1派生和继承的相关概念和作用6classStudent1:publicStudent//声明基类是Student{private:intage;//新增加的数据成员stringaddr;//新增加的数据成员public:voiddisplay_1()//新增加的成员函数{coutage:ageendl;coutaddress:addrendl;}};5.1派生和继承的相关概念和作用7类A派生类B:类A为基类,类B为派生类。AB新增加的成员数据和成员函数5.1派生和继承的相关概念和作用8在C++语言中,一个派生类可以从一个基类派生,也可以从多个基类派生。从一个基类派生的继承称为单继承;从二个或多个基类派生的继承称为多重继承。通过继承机制,可以利用已有的数据类型来定义新的数据类型。所定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧的成员。5.1派生和继承的相关概念和作用9在建立派生类的过程中,基类不会做任何改变;派生类则除了继承基类的所有可引用的成员变量和成员函数外,还可另外定义本身的成员变量和处理这些变量的函数由于派生类可继承基类的成员变量和成员函数,因此在基类中定义好的数据和函数等的程序代码可重复使用,这样可以提高程序的可靠性。5.1派生和继承的相关概念和作用10当从已有的类中派生出新的类时,可以对派生类做以下几种变化:1、可以继承基类的成员数据或成员函数。2、可以增加新的成员变量。3、可以增加新的成员函数。4、可以重新定义已有的成员函数。5、可以改变现有的成员属性。5.1派生和继承的相关概念和作用11类A派生类B:类A为基类,类B为派生类。AB但派生并不是简单的扩充,有可能改变派生类中的基类的成员性质。有三种派生方式:公有派生、保护派生、私有派生。默认的是私有派生。classB:publicA{...};classB:protectedA{...};classB:privateA{...};classB:A{...};A为私有派生5.2三种继承的派生类的成员访问方式12从一个基类派生一个类的一般格式为:classClassName:AccessBaseClassName{private:......;//私有成员说明public:......;//公有成员说明protected:......;//保护成员说明}派生类名基类名继承方式public:表示公有基类private:表示私有基类(默认)protected:表示保护基类派生类中新增加的成员5.2三种继承的派生类的成员访问方式13公有派生classClassName:publicBaseClassName公有派生时,基类中所有成员在派生类中保持各个成员的访问权限。公有派生,派生类中保持基类的成员特性基类成员属性派生类中派生类外公有可以引用可以引用保护可以引用不可引用私有不可引用不可引用5.2三种继承的派生类的成员访问方式14x(私有)y(保护)z(公有)Getx()Gety()ShowA()Ax(私私有)y(保护)z(公有)Getx()Gety()ShowA()Bm(私有)n(私有)B()Show()Sum()publicx在类B新增成员中不能直接调用y在类B中可以调用z在整个文件中可以调用对类B的对象初始化即是对x,y,z,m,n等全部成员的初始化5.2三种继承的派生类的成员访问方式15classA{intx;protected:inty;public:intz;A(inta,intb,intc){x=a;y=b;z=c;}//基类初始化intGetx(){returnx;}//返回xintGety(){returny;}//返回yvoidShowA(){coutx=x'\t'y=y'\t'z=z'\n';}};classB:publicA{intm,n;public:B(inta,intb,intc,intd,inte):A(a,b,c){m=d;n=e;}voidShow(){cout“m=m'\t'“n=n'\n';coutx=Getx()'\t'y=y'\t'z=z'\n';}intSum(){return(Getx()+y+z+m+n);}};voidmain(){Bb1(1,2,3,4,5);b1.ShowA();b1.Show();coutSum=b1.Sum()'\n';coutx=b1.Getx()'\t';couty=b1.Gety()'\t';coutz=b1.z'\n';}公有派生对基类初始化因为x是基类私有,所以在派生类和类外中不能直接引用因为y是基类保护,所以在派生类中可以直接引用。而在类外不可直接引用。因为z是基类公有,所以在派生类中和类外均可直接引用。5.2三种继承的派生类的成员访问方式仅对派生类中的新增成员进行初始化16私有派生classClassName:privateBaseClassName此时,基类中公有成员和保护成员在派生类中均变为私有,在派生类中仍可直接使用这些成员,基类中的私有成员,在派生类中不可直接使用。基类成员属性派生类派生类外公有可以引用不可引用保护可以引用不可引用私有不可引用不可引用基类:public:(变为私有)在派生类中使用,类外不可使用protected:(变为私有)在派生类中使用,类外不可使用private:不能在派生类中和类外使用5.2三种继承的派生类的成员访问方式17x(私有)y(保护)z(公有)Getx()Gety()ShowA()Ax(私私有)y(私有)z(私有)Getx()Gety()ShowA()Bm(私有)n(私有)B()Show()Sum()privatex在类B新增加的成员中不能直接调用y在类B中可以调用z在类B中可以调用对类B的对象初始化即是对x,y,z,m,n等全部成员的初始化均为私有类B外不能引用5.2三种继承的派生类的成员访问方式18classA{intx;protected:inty;public:intz;A(inta,intb,intc){x=a;y=b;z=c;}//基类初始化intGetx(){returnx;}//返回xintGety(){returny;}//返回yvoidShowA(){coutx=x'\t'y=y'\t'z=z'\n';}};classB:privateA{intm,n;public:B(inta,intb,intc,intd,inte):A(a,b,c){m=d;n=e;}voidShow(){cout“m=m'\t'“n=n'\n';coutx=Getx()'\t'y=y'\t'z=z'\n';}intSum(){return(Getx()+y+z+m+n);}};voidmain(void){Bb1(1,2,3,4,5);b1.ShowA();b1.Show();coutSum=b1.Sum()'\n';coutx=b1.Getx()'\t';couty=b1.Gety()'\t';coutz=b1.z'\n';}私有派生对基类初始化因为x是基类私有,所以在派生类和类外中不能直接引用y是基类保护,所以在派生类中可以直接引用。而在类外不可直接引用。z是基类公有,私有派生变为私有,所以在派生类中可直接引用,而在类外不可。这些函数都是基类公有,在类外不可使用。Aa1(1,2,3);a1.ShowA();19保护派生classClassName:protectedBaseClassName此时,基类中公有和保护成员在派生类中均变为保护的,在派生类中仍可直接使用这些成员,基类中的私有成员,在派生类中不可直接使用。基类成员属性派生类派生类外公有可以引用不可引用保护可以引用不可引用私有不可引用不可引用基类:public:(变为保护)在派生类中使用,类外不可使用protected:(仍为保护)在派生类中使用,类外不可使用private:不能在派生类中和类外使用5.2三种继承的派生类的成员访问方式20x(私有)y(保护)z(公有)Getx()Gety()ShowA()Ax(私私有)y(保护)z(保护)Getx()Gety()ShowA()Bm(私有)n(私有)B()Show()Sum()protectedx在类B新增加的成员中不能直接调用y在类B中可以调用z在类B中可以调用对类B的对象初始化即是对x,y,z,m,n等全部成员的初始化均为保护类B外不能引用5.2三种继承的派生类的成员访问方式21protected成员是一种具有血缘关系内外有别的成员。它对派生类的对象而言,是公开成员,可以访问,对血缘外部而言,与私有成员一样被隐蔽。5.2三种继承的派生类的成员访问方式22当定义了一个类,这个类只能用作基类来派生出新的类,而不能用这种类来定义对象时,称这种类为抽象类。当对某些特殊的对象要进行很好地封装时,需要定义抽象类。将类的构造函数或析构函数的访问权限定义为保护的时,这种类为抽象类。5.3抽象类与保护的成员函数23当把类中的构造函数或析构函数说明为私有的时,所定义的类通常是没有任何实用意义的,一般情况下,不能用它来产生对象,也不能用它来产生派生类。5.3抽象类与保护的成员函数24x(私有)y(私有)A()(保护)ShowA()(公有)Ax(私私有)y(私私有)A()(保护)ShowA()Bm(私有)B()Show()public在类B中不能定义A的对象在任何时候都不能定义A的对象但可以在初始化类B的对象时初始化原类A中的成员,因为A()在类B中是可以被调用的。5.3抽象类与保护的成员函数25classA{intx,y;protected:A(inta,intb){x=a;y=b;}//基类初始化public:voidShowA(){coutx=x'\t'y=y'\n';}};classB:publ