C--程序设计教程(第二版)

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

18:29:551C++程序设计教程(第二版)第十章继承Chapter10Inheritance清华大学出版社钱能18:29:552第十章继承1.继承结构(InheritanceStructure)2.访问父类成员(AccessFather’sMember)3.派生类的构造(ConstructingDerivedClasses)4.继承方式(InheritanceMode)5.继承与组合(Inheritance&Composition)6.多继承概念(Multi-InheritanceConcept)7.多继承技术(Multi-InheritanceTechnology)18:29:5531.继承结构(InheritanceStructure)类层次结构宇宙万事万物都是分类分层的,解决问题可以从事物之间的上下关系中着手.这是继承引入程序设计的前提.例如:各类型的交通工具之间具有继承关系。18:29:554交通工具汽车小汽车大卡车大客车工具车轿车面包车图10-1继承的类层次18:29:555基类(父类):派生新类的类派生类(子类):从基类派生而成的类基类和派生类:构成类的层次关系单继承:从一个基类派生而成的类多继承:从多个基类派生而成的类继承方式:公有继承、私有继承、保护继承18:29:556派生类的定义语法:class派生类名:访问控制基类名{…};访问控制:public、protected、private缺省为:private继承方式⑴公有继承派生时用“public”作访问控制⑵私有继承派生时用“private”作访问控制⑶保护继承派生时用“protected”作访问控制18:29:557继承方式继承方式与访问控制:访问控制符继承方式public公有继承private私有继承protected保护继承注意:如果类之间没有继承关系则保护成员和私有成员类似;但在类的继承关系中,保护成员在其子类中可以被直接访问,而私有成员在它的子类中也不能被直接访问。18:29:558公有继承:基类的公有段成员被继承为公有的,基类的保护段成员被继承为保护的。派生时用“public”作访问控制。保护继承:基类的公有段成员和保护段成员被继承为保护的,派生时用“protected”作访问控制。私有继承:基类的公有段成员和保护段成员被继承为私有的,派生时用“private”作访问控制。基类的私有成员在任何情况下都是基类所私有的,在基类以外都不能访问!18:29:559公有成员:一个类的公有成员允许本类的成员函数、本类的对象、派生类的成员函数、公有派生类的对象直接访问,不允许保护和私有派生类的对象直接访问。私有成员:一个类的私有成员只允许本类的成员函数直接访问。保护成员:允许本类的成员函数、派生类的成员函数直接访问,不允许对象直接访问。18:29:5510基类访问控制符继承方式publicprotectedprivatepublicpublicprotected隔离protectedprotectedprotected隔离privateprivateprivate隔离18:29:5511例如:一个含有不同继承方式的类的继承结构。classBase{intb1;protected:intb2;voidfb2(){b1=1;}public:intb3;voidfb3(){b1=1;}};18:29:5512classPri:privateBase{public:voidtest(){b1=1;//errorb2=1;//okb3=1;//okfb2();//okfb3();//ok}};classFromPri:publicPri{public:voidtest(){b1=1;//errorb2=1;//errorb3=1;//errorfb2();//errorfb3();//error}};18:29:5513classPro:protectedBase{public:voidtest(){b1=1;//errorb2=1;//okb3=1;//okfb2();//okfb3();//ok}};classFromPro:publicPro{public:voidtest(){b1=1;//errorb2=1;//okb3=1;//okfb2();//okfb3();//ok}};18:29:5514classPub:publicBase{public:voidtest(){b1=1;//errorb2=1;//okb3=1;//okfb2();//okfb3();//ok}};classFromPub:publicPub{public:voidtest(){b1=1;//errorb2=1;//okb3=1;//okfb2();//okfb3();//ok}};18:29:5515intmain(){PripriObj;priObj.b1=1;//errorpriObj.b2=1;//errorpriObj.b3=1;//errorProproObj;proObj.b1=1;//errorproObj.b2=1;//errorproObj.b3=1;//errorPubpubObj;pubObj.b1=1;//errorpubObj.b2=1;//errorpubObj.b3=1;//ok}18:29:5516说明:私有继承时,基类中不管是公有的,还是保护的,一律在子类中变成私有成员。保护继承时,基类中公共和保护的成员在子类中变成保护的。公共继承时,基类中为公共、保护的成员在子类中仍保持为公共、保护的。在继承关系中,基类的private成员不但对应用程序隐藏,对派生类也隐藏。而基类的保护成员则只对应用程序隐藏,而对派生类则毫不隐瞒。18:29:5517在派生类中,可以调整成员的访问控制属性!classBase{intb1;protected:intb2;voidfb2(){b1=1;}public:intb3;voidfb3(){b1=1;}};classPri:privateBase{public:usingBase::fb3;//fb3从私有转为公有usingBase::b1;//error!b1不可见};intmain(){Pripri;pri.fb3();//ok}18:29:5518说明:在派生类中调整访问控制属性的前提是在派生类中该成员必须是可见的注意:在写程序时,数据成员一般设置为私有的;18:29:5519派生类对象结构对于下面的继承关系:classFather{inta,b;public://成员函数};classSon:publicFather{intc;public://成员函数};基类对象子类对象说明:派生类中含有基类的数据成员,子类对象空间总是不小于基类对象cabab基类部分子类添加部分18:29:55202.访问父类成员(AccessFather’sMember)继承父类成员例如:有一个学生类Student,现在要增加研究生类,研究生类除了自己所特有的性质外,还具有学生类的所有性质,下面用继承的方法来重用学生类的代码。18:29:5521classAdvisor{//导师类intnoOfMeeting;};classStudent{//学生类stringname;intsemesterHours;//学时doubleaverage;//平均分public:Student(stringpName=noName):name(pName),average(0),semesterHours(0){}18:29:5522voidaddCourse(inthours,doublegrade){doubletotalGrade=(semesterHours*average+grade);//总分semesterHours+=hours;//总修学时average=semesterHours?totalGrade/semesterHours:0;//平均分}voiddisplay(){coutname=\name\,hours=“semesterHours,average=average\n;}intgetHours(){returnsemesterHours;}doublegetAverage(){returnaverage;}};18:29:5523classGraduateStudent:publicStudent{//研究生类(继承学生类)Advisoradvisor;//导师intqualifierGrade;//资格考试分数public:intgetQualifier(){returnqualifierGrade;}};intmain(){Studentds(Loleeundergrade);GraduateStudentgs;ds.addCourse(3,2.5);ds.display();gs.addCourse(3,3.0);gs.display();}运行结果:name=LoleeUndergrad,hours=3,average=0.833333name=noname,hours=3,average=118:29:5524voidfn(Student&s){//…}voidmain(){GraduateStudentgs;fn(gs);}函数fn()期望接受Student类对象作为它的参数,来自main()的调用传给它一个GraduateStudent类对象,fn()把它视作Student类对象予以接受。事实上,GraduateStudent的内存布局,也与“gs是研究生,当然也是学生”相吻合。Student部分GraduateStudent部分this指针GraduateStudent对象18:29:5525说明:捆绑子类对象可以访问父类成员函数和自身成员函数;捆绑基类对象只能访问基类成员函数,不能访问子类成员函数:ds.addCourse(3,2.5);ds.display();ds.getQualifier();//errorgs.addCourse(3,3.0);gs.display();gs.getQualifier();18:29:5526classFather{inta;protected:voidfp(){couta;}public:voidprint(){couta;}};外来用户:voidfn(){Sond;d.print();//okd.disp();//okd.fp();//errorFatherf;f.print();//okf.fp();//errorf.disp();//error}子类用户:classSon:publicFather{intb;public:voiddisp(){fp();//okprint();//ok}voided(){a++;}//error};18:29:55273.构造子类对象(ConstructingObjectsofSubClass)继承中的构造函数和析构函数的说明:1.派生类构造函数的初始化列表中列出的均是直接基类的构造函数。2.构造函数不能被继承,因此派生类的构造函数只能通过调用基类的某个构造函数(如果有定义的话)来初始化基类子对象。3.派生类的构造函数只负责初始化自己定义的数据成员。18:29:55284.派生类构造函数被调用时,在还没有执行构造函数体之前,先调用基类的构造函数,再调用派生类对象成员所属类的构造函数,完成对象所需空间的分配;最后执行派生类自身的构造函数。(若基类上面还有基类,优先调用上面基类的构造函数;派生类的对象成员的构

1 / 61
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功