版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第4章派生类与继承第4章派生类与继承1继承在已有类的基础上建立一个新类的过程称为继承被继承的已有类称为基类(父类)派生在已有类的基础上新增自己的特性(属性与行为)而产生新类的过程称为派生派生出的新类称为派生类(子类)继承与派生的目的:实现代码的重用与扩充继承继承与派生的目的:实现代码的重用与扩充24.1派生类的概念4.1.1继承单继承派生类只从一个基类派生4.1派生类的概念4.1.1继承3多重继承一个派生类有两个或多个基类多重继承4多级派生(多层派生)派生类又作为基类,继续派生新的类多级派生(多层派生)54.1.2派生类的声明class派生类名:[继承方式]基类名{//派生类新增的数据成员和成员函数};
继承方式:规定了如何访问从基类继承的成员,可以是private,protected,public三种方式.4.1.2派生类的声明6//定义一个基类classPerson{
public:voidprint(){//……}
protected:stringname;intage;charsex;
};//定义一个派生类classEmployee:publicPerson{public:voidprint1(){……….}private:stringdepartment;floatsalary;
};//定义一个基类//定义一个派生类7由类Person继承出类Employee有三种继承方式
(1)公有继承classemployee:publicperson{//…};
(2)私有继承classemployee:privateperson{//…};
(3)保护继承classemployee:protectedperson{//…};由类Person继承出类Employee有三种继承方式84.1.3派生类的构成派生类除了可以从基类继承成员外,还可以增加自己的数据成员和成员函数.这些新增的成员正是派生类不同于基类的关键所在,是派生类对基类的发展.Person类stringname;intage;charsex;voidprint();Employee类stringname;intage;charsex;voidprint()继承
新增(发展)stringdepartment;floatsalary;voidprint1();继承与派生的目的:实现代码的重用与扩充4.1.3派生类的构成Person类stringname;9构造一个派生类一般过程:(1)派生类从基类接收成员C++继承中,派生类把基类的全部成员(构造函数与析构函数除外)接收过来.(2)调整从基类接收来的成员(3)在派生类中增加新成员.构造一个派生类一般过程:104.1.4基类成员在派生类中的访问属性派生类继承基类中全体成员(除了构造函数与析构函数).这些成员的访问属性在派生程中可以调整.从基类继承来的成员在派生类的访问属性是由继承方式控制.
class派生类名:[继承方式]基类名
{//…….}继承方式为public,protected,private.不同的继承方式,导致不同访问属性的基类成员在派生类的访问属性有所不同.用公有继承方式建立的派生类称为公有派生类用私有继承方式建立的派生类称为私有派生类用保护继承方式建立的派生类称为保护派生类4.1.4基类成员在派生类中的访问属性11基类中的成员在公有派生类中的访问属性在私有派生类中的访问属性在保护派生类中的访问属性私有成员公有成员保护成员不可直接访问公有保护不可直接访问私有私有不可直接访问保护保护表:基类成员在派生类中的访问属性基类中的成员在公有派生类中的访问属性在私有派生类中的访问属性124.1.5派生类对基类成员的访问规则类的继承方式有
public(公有继承)protected(保护继承)private(私有继承)不同的继承方式导致原来具有不同访问属性的基类成员在派生类中的访问属性不同.派生类对基类成员的访问形式有以下两种:(1)内部访问,派生类的新增成员函数对基类继承的成员的访问(2)对象访问,在派生类的外部,以派生类的对象对基类继承来的成员的访问.4.1.5派生类对基类成员的访问规则131.私有继承的访问规则基类成员private成员public成员protected成员内部访问对象访问
不可访问不可访问可访问不可访问可访问不可访问基类中的private成员,既不能被派生类的对象访问,也不能被派生类的新增成员函数访问(内部访问)..1.私有继承的访问规则基类成员private成员pu14classBase{public:voidsetx(intn){x=n;}voidshowx(){cout<<x<<endl;}private:intx;}classDerived:privateBase{public:voidsetxy(inin,intm){setx(n);y=m;}voidshowxy();{cout<<x;cout<<y<<endl}private:inty;}intmain(){Derivedobj;obj.setx(10);obj.showx();obj.setxy(20,30);obj.showxy();return0;}╳╳╳classBaseintmain()╳╳╳152.公有继承的访问规则基类成员private成员public成员protected成员内部访问对象访问
不可访问不可访问可访问可访问可访问不可访问2.公有继承的访问规则基类成员private成员pu16classBase{public:voidsetxy(intm,intn){x=m;y=n;}voidshowxy(){cout<<x<<y<<endl;}private:intx;protected:inty;}classDerived:publicBase{public:voidsetxyz(inim,intn,intl){setxy(m,n);z=l;}voidshowxyz();{cout<<x;cout<<y;cout<<z;}private:intz;}intmain(){Derivedobj;obj.setxyz(30,40,50);obj.showxy();obj.y=60;obj.showxyz();return0;}╳╳classBaseintmain()╳╳173.保护继承的访问规则基类成员private成员public成员protected成员内部访问对象访问
不可访问不可访问可访问不可访问可访问不可访问3.保护继承的访问规则基类成员private成员pu184.2派生类的构造函数与析构函数派生类继承了基类的成员,实现了代码的重用,引入继承更主要的目的是代码的扩充.所以,只有在派生类中加入新成员,派生才更有实际意义.派生类不能继承基类的构造函数,在派生类中对新增成员的初始化,加入派生类的构造函数,基类继承下来的成员初始化有基类构造函数完成.同样,当搞清对象时,也需要加入派生类的析构函数来执行清理工作.4.2派生类的构造函数与析构函数派生类继承了基类的成员,实现194.2.1派生类构造函数和析构函数的执行顺序当创建派生类对象时,首先执行基类的构造函数,随后再执行派生类的构造函数;当撤消派生类的对象时,则先执行派生类的析构函数,随后再执行基类的析构函数.4.2.1派生类构造函数和析构函数的执行顺序当创建派生20例:classBase{public: Base(){cout<<"Constructingbaseclass\n";}~Base(){cout<<"Destructingbaseclass\n";}}; classDerive:publicBase{public:Derive(){cout<<"Constructingderivedclass\n";}~Derive(){cout<<"Destructingderivedclass\n";}};intmain(){Deriveop;return0;}
ConstructingbaseclassConstructingderivedclassDestructingderivedclassDestructingbaseclass例:Constructingbaseclass214.2.1派生类构造函数和析构函数的构造规则1.简单派生类的构造函数
当基类的构造函数没有参数,或没有显示定义构造函数时,派生类可以不向基类传递参数,甚至可以不定义构造函数.
当基类含有带参数的构造函数时,由于派生类不能继承基类的构造函数与析构函数,此时,派生类必须定义构造函数,以提供把参数传递给基类构造函数的途径.4.2.1派生类构造函数和析构函数的构造规则1.简单派生类22在C++中派生类构造函数的一般形式为:派生类名(参数总表):基类名(参数表){
//……派生类新增数据成员的初始化语句}其中:基类构造函数的参数,通常来源于派生类构造函数的参数总表.也可用常数值.在C++中派生类构造函数的一般形式为:23classStudent{public:Student(intnumber1,stringname1,floatscore1){number=number1;name=name1;score=score1;}voidprint(){cout<<“number:”<<number<<endl;cout<<“name:”<<name<<endl;cout<<“score:”<<score<<endl;}protected:intnumber;stringname;floatscore;}classStudent24classUStudent:publicStudent{public:
UStudent(intnumber1,stringname1,floatscore1,stringmajor1):Student(number1,name1,score1){major=major1;}voidprint1(){print();cout<<“major:”<<major<<endl;}private:stringmajor;};intmain(){UStudentstu(001,”张三”,95,”信息工程”);stu.print1();return0;}classUStudent:publicStudenti25说明:(1)可以将派生类的构造函数定义在类的外部,类体内只写该函数的声明.在类中声明派生类的构造函数时,不包括基类构造函数名及其参数表.只在类外定义构造函数时才将它列出来.classUStudent:publicStudent{public:
UStudent(intnumber1,stringname1,floatscore1,stringmajor1);voidprint1(){print();cout<<“major:”<<major<<endl;}private:stringmajor;};UStudent::UStudent(intnumber1,stringname1,floatscore1,stringmajor1):Student(number1,name1,major1){major=major1;}说明:classUStudent:publicStude26(2)如果基类使用默认构造函数或不带参数的构造函数,则在派生类中定义构造函时可以去掉”:基类构造函数名(参数表)”,此时若派生类不需要构造函数,则可不定义派生类的构造函数.派生类名(参数总表){
//……派生类新增数据成员的初始化语句}(2)如果基类使用默认构造函数或不带参数的构造函数,则在派生27(3)当基类的构造函数不带参数时,派生类不一定需要定义构造函数,然而当基类的构造函数哪怕只带一个参数,它所有的派生类都必须定义构造函数,甚至所定义的派生类函数可能为空,仅仅起到参数传递作用.(3)当基类的构造函数不带参数时,派生类不一定需要定义构造函282.派生类的析构函数在派生类中可以根据需要定义自己的析构函数,用于对派生类中新增加的成员进行清理工作,基类的清理工作仍然由基类的构造函数负责.
析构函数是无参的函数.2.派生类的析构函数293.含有对象成员的(子对象)的派生类的构造函数当派生类中含有内嵌的对象成员(子对象)时,其构造函数的一般形式为:
派生类名(参数总表):基类名(参数表0),对象成员名1(参数表1),……,对象成员名n(参数表n){
//派生类新增数据成员的初始化语句
}
在定义派生类对象时,构造函数执行顺序(1)调用基类的构造函数(2)调用内嵌对象成员的构造函数(内嵌对象成员有多个,执行顺序与在类中的声明顺序一致)(3)调用基类的构造函数撤消对象时,析构函数的调用顺序与构造函数正好相反3.含有对象成员的(子对象)的派生类的构造函数30classBase{public:Base(inti){x=I;cout<<“Constructingbaseclass\n”;}~Base(){cout<<“Destructingbaseclass\n”;}voidshow(){cout<<x<<endl;}private:intx;};classDerived:publicBase{public:Derived(inti):Base(i),d(i){cout<<“Constructingderivedclass\n”}~Derived(){cout<<“Destructingderivedclass\n”}private:Based;}intmain(){Derivedobj(5);obj.show();return0;}ConstructingbaseclassConstructingbaseclassConstructingderivedclass5DestructingderivedclassDestructingbaseclassDestructingbaseclassclassBaseintmain()Constructi314.3调整基类成员在派生类中的访问属性的其他方法4.3.1同名成员
派生类中定义了与基类成员同名的成员,则派生类成员覆盖了基类的同名成员,在派生类中使用这个名字意味着访问在派生类中重新说明的成员.为了能够使用基类的同名成员,必须采用如下形式:
基类名::成员名4.3调整基类成员在派生类中的访问属性的其他方法4.3.132classA{public:A(intx1){x=x1;}voidprint(){cout<<“x=“<<x<<endl;;}private:intx;};classB:publicA{public:B(intx1,inty1):A(x1){y=y1}voidprint(){A::print();cout<<“y=“<<y<<endl;}private:inty;}intmain(){Bb(10,20);b.print2();return0;}X=10classAintmain()X=1033说明:
在面向对象程序设计中,若要在派生类中对基类继承过来的某些函数功能进行扩充和改造,都可以采用这样覆盖的方法实现.说明:344.3.2访问声明
访问声明的方法是把基类的保护成员或公有成员直接写至私有派生类定义式中的同名段中,同时给成员名前加以基类名和作用域标识符::.利用这种方法,该成员就成为派生类的保护成员或公有成员了.4.3.2访问声明35classA{public:A(intx1){x=x1;}voidprint(){cout<<“x=“<<x;}private:intx;};classB:privateA{public:B(intx1,inty1):A(x1){y=y1}voidprint2(){print();}private:inty;}intmain(){Bb(10,20);b.print2();return0;}X=10classAintmain()X=
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 小学三年级英语下册 Unit 6 Lesson 2 Its time for class 教学设计
- 第3节 信息的处理教学设计初中信息技术(信息科技)七年级下册粤教清华版
- 初中地理商务星球版七年级下册第七章 各具特色的地区第一节 东南亚教学设计
- 2026广东省南方医科大学珠江医院三水医院第二批合同制工作人员招聘26人备考题库含答案详解【典型题】
- 2026年万家寨水务控股集团有限公司校园招聘考试参考题库及答案解析
- 2026年北京内蒙古大厦校园招聘考试参考试题及答案解析
- 2026辽宁铁岭市昌图县14家单位补充招聘公益性岗位人员23人备考题库【学生专用】附答案详解
- 2026重庆长江轴承股份有限公司招聘122人备考题库附参考答案详解【达标题】
- 2026广东云浮市新兴县招募见习岗位人员2人备考题库(重点)附答案详解
- 2026西藏拉萨墨竹工卡县机关事业单位编外聘用人员招聘5人备考题库及答案详解【有一套】
- 绿化保洁安全培训课件
- 知道智慧树系统思维与系统决策满分测试答案
- 工会宣传教育工作课件
- 海康门禁系统产品技术方案
- 2025年新疆高端会计人才笔试题及答案
- 营养学电子课件
- 设备升级改造管理制度
- 台球俱乐部规章管理制度
- 2025年4月自考06091薪酬管理试题及答案
- 2025年浙江宁波城建投资集团有限公司招聘笔试参考题库含答案解析
- 高中生艾滋病预防教育课件
评论
0/150
提交评论