




已阅读5页,还剩64页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第5章继承与派生 2012 2 21 2 本章主要内容 类的继承与派生派生类派生类的继承方式与访问属性派生类的构造函数和析构函数多继承赋值兼容原则 3 继承与派生问题 客观世界中概念的层次结构 视角 从下往上看 保持已有的特性 继承视角 从上往下看 增加了新的特性 派生 继承 派生 4 继承与派生问题举例 1 5 继承与派生问题举例 2 6 类的继承与派生 1 类的层次结构类的继承 一个新类从原有的类那里获得其已有的特性类的派生 从已有的类产生一个新的类基类 父类 派生新类的类派生类 子类 从基类派生而成的类 学生类 研究生 基类 7 类的继承与派生 2 基类和派生类 构成类的层次关系单派生 派生一个子类的类多派生 派生多个子类的类 学生类 研究生 基类 例如上图 单派生 大学生派生研究生 多派生 除了一个单派生其余的都是多派生 多派生 8 类的继承与派生 3 基类和派生类 构成类的层次关系单继承 仅从一个基类派生而成的类多继承 从多个基类派生而成的类 派生类 在职研究生 研究生 在职人员 在面向对象程序设计中使用继承和派生有什么好处 如何使用 多继承 例如上图 单继承 教师和职员都是单继承 只有一个父类 多继承 在职研究生就是多继承 有两个父类 9 类的继承与派生 4 classPerson 人的基本信息 charName 20 charSex intAge public voidRegister char name charsex intage strcpy Name name Sex sex m m f Age age voidShowMe cout Name t Sex t Age endl 10 类的继承与派生 5 classStudent 学生类 charName 20 charSex intAge intNumber 学号charClassName 10 班级public voidRegisterStu char name intsex charage intnumber char classname strcpy Name name Sex sex m m f Age age Number number strcpy ClassName classname voidShowStu cout Name t Sex t Age endl cout Number t ClassName endl 从这个例子我们能发现什么 能否利用已有的代码 11 类的继承与派生 6 classStudent publicPerson 公有继承 intNumber 学号charClassName 10 班级public voidRegisterStu char name intsex charage intnumber char classname Register name sex age 直接调用基类的公有成员Number number strcpy ClassName classname voidShowStu ShowMe 直接调用基类的公有成员cout Number t ClassName endl 继承与派生 Student是派生类 Person是基类继承已有的特性 派生新的特性 12 继承的目的 保持已有的特性 实现代码重用 派生的目的 增加新的特性 适应新的需要 类的继承 保留已有的数据成员和成员函数类的派生 增加新的数据成员和成员函数 类的继承与派生 7 在面向对象程序设计中如何使用继承和派生 13 派生类的定义格式class派生类名 继承方式基类名 新增成员声明 继承方式公有继承 public 私有继承 private 保护继承 protected 派生类定义 14 派生类对象结构 classA inta b classB publicA intc 基类A对象子类B对象 派生类对象中总是含有基类对象 即含有基类的数据成员 其空间总是不小于基类对象 15 类的成员访问属性有三种 public 公有 private 私有 和protected 保护 在类内 非静态成员函数可以访问类中的所有成员 在类外 通过类的 对象 成员 方式只能访问该类的公有成员 类的继承方式有三种 public 公有继承 private 私有继承 和protected 保护继承 在派生类中继承来的成员访问属性是什么 继承来的成员是不是都可以直接访问 派生类的继承方式和访问属性 1 16 继承方式下的访问权限 17 派生类的继承方式和访问属性 2 public 公有继承 classPerson charName 20 charSex intAge public voidRegister char name charsex intage strcpy Name name Sex sex m m f Age age voidShowMe cout Name t Sex t Age endl classStudent publicPerson 公有继承 intNumber 学号charClassName 10 班级public voidRegisterStu char name intsex charage intnumber char classname Register name sex age Age age Number number strcpy ClassName classname voidShowStu ShowMe cout Number t ClassName endl 18 派生类的继承方式和访问属性 续 public 公有继承 intmain Studentstu 定义一个对象stu RegisterStu 张弓长 m 18 85071011 计算机51 本类中的公有成员函数stu Age 18 基类的私有数据成员stu Number 110012315 本类中的私有数据成员stu ShowStu 本类中的公有成员函数stu ShowMe 基类的 成为派生类的公有成员函数return0 19 派生类的继承方式和访问属性 续 public 公有继承 classPerson protected charName 20 charSex intAge public voidRegister char name charsex intage strcpy Name name Sex sex m m f Age age voidShowMe cout Name t Sex t Age endl classStudent publicPerson 公有继承 intNumber 学号charClassName 10 班级public voidRegisterStu char name intsex charage intnumber char classname Register name sex age Age age Number number strcpy ClassName classname voidShowStu ShowMe cout Number t ClassName endl 20 派生类的继承方式和访问属性 3 protected 保护继承 classPerson charName 20 charSex intAge public voidRegister char name charsex intage strcpy Name name Sex sex m m f Age age voidShowMe cout Name t Sex t Age endl classStudent protectedPerson 保护继承 intNumber 学号charClassName 10 班级public voidRegisterStu char name intsex charage intnumber char classname Register name sex age Age age Number number strcpy ClassName classname voidShowStu ShowMe cout Number t ClassName endl 21 派生类的继承方式和访问属性 续 protected 保护继承 intmain Studentstu stu RegisterStu 张弓长 m 18 85071011 计算机51 stu Age 18 基类的私有数据成员stu ShowStu stu ShowMe 成为派生类的保护成员return0 22 派生类的继承方式和访问属性 续 protected 保护继承 classPerson protected charName 20 charSex intAge public voidRegister char name charsex intage strcpy Name name Sex sex m m f Age age voidShowMe cout Name t Sex t Age endl classStudent protectedPerson 保护继承 intNumber 学号charClassName 10 班级public voidRegisterStu char name intsex charage intnumber char classname Register name sex age Age age Number number strcpy ClassName classname voidShowStu ShowMe cout Number t ClassName endl 23 派生类的继承方式和访问属性 4 private 私有继承 classPerson charName 20 charSex intAge public voidRegister char name charsex intage strcpy Name name Sex sex m m f Age age voidShowMe cout Name t Sex t Age endl classStudent privatePerson 私有继承 intNumber 学号charClassName 10 班级public voidRegisterStu char name intsex charage intnumber char classname Register name sex age Age age Number number strcpy ClassName classname voidShowStu ShowMe cout Number t ClassName endl 24 派生类的继承方式和访问属性 续 private 私有继承 intmain Studentstu stu RegisterStu 张弓长 m 18 85071011 计算机51 stu Age 18 stu ShowStu stu ShowMe 成为派生类的私有成员return0 25 在派生类中不管什么继承方式 只能访问父类的公有成员和保护成员 不能访问父类的私有成员 在派生类外 通过派生类对象不管什么继承方式 只能访问公有成员 包括新增的和继承的 不能访问保护成员和私有成员 包括新增的和继承的 小结 26 classBase private inta voidf cout a protected intb voidg cout b public intc voidk cout c classSub publicBase public voidtest a 1 f b 2 g c 3 k voidmain Subd d a 1 d f d b 2 d g d c 3 d k 练习1 27 classBase private inta voidf cout a protected intb voidg cout b public intc voidk cout c classSub protectedBase public voidtest a 1 f b 2 g c 3 k voidmain Subd d a 1 d f d b 2 d g d c 3 d k 练习2 28 classBase private inta voidf cout a protected intb voidg cout b public intc voidk cout c classSub privateBase public voidtest a 1 f b 2 g c 3 k intmain Subd d a 1 d f d b 2 d g d c 3 d k 练习3 protected继承与private继承的区别 29 classA intmyPrivate protected intmyProtected public intmyPublic classB1 protectedA voidSetNum myProtected 1 myPublic 1 classC1 publicB1 voidSetNum myProtected 1 myPublic 1 classB2 privateA voidSetNum myProtected 1 myPublic 1 classC2 publicB2 voidSetNum myProtected 1 myPublic 1 多层派生 1 30 不管有多少层派生 对某一个派生类来说派生类中继承成员的访问属性 只由其在直接父类的访问属性和继承方式确定 派生类中新增成员的访问属性 由其在类中的定义确定 多层派生 2 31 基类的构造函数和析构函数都不能被继承 派生类中需要声明自己的构造函数和析构函数 在设计派生类的构造函数时候 不仅要考虑派生类所新增的数据成员初始化 还要考虑基类的数据成员初始化 声明构造函数时 除了对本类中新增成员进行初始化外 对继承来的基类成员的初始化 需用初始化列表调用基类构造函数完成 派生类的构造函数 1 32 派生类构造函数的一般形式派生类名 总参数表 基类名1 参数表1 基类名2 参数表2 对象成员名1 对象参数表1 对象成员名2 对象参数表2 派生类中新增数据成员的初始化 有三种数据要考虑初始化 基类中的数据成员初始化 基类构造函数本类中的对象成员初始化 相应类的构造函数本类中新增的数据成员 函数体 派生类的构造函数 2 33 派生类构造函数说明 总参数表 包括派生类中新增加的数据成员 以及全部基类和全部对象成员的所有参数 如果基类中没有定义构造函数 或定义了没有参数的构造函数 默认构造函数 则在初始化列表中可略去 基类名 参数表 此时 若派生类及对象成员都不需初始化 则可以不定义派生类的构造函数 如果基类中定义的构造函数带参数 则必须定义派生类构造函数 并通过初始化列表传递参数 如果基类中既定义无参的构造函数 又定义了有参的构造函数 在定义派生类构造函数时 既可以包含基类构造函数及其参数 也可以不包含基类构造函数 派生类的构造函数 3 34 派生类的构造函数 4 派生类默认构造函数如果没有定义构造函数 则会调用默认的无参构造函数 派生类的默认构造函数首先会调用父类的无参构造函数 如果父类定义了有参构造函数 又没有重载无参构造函数 则编译错误 如果父类的上面还有父类 则依次类推 35 派生类构造函数执行次序 调用基类构造函数 调用顺序按照被声明时的顺序调用对象成员构造函数 调用顺序按照被声明时的顺序执行派生类构造函数体 派生类的构造函数 5 36 析构函数也不被继承 派生类需自行声明 声明方法与一般 无继承关系时 类的析构函数相同 不需要显式地调用基类的析构函数 系统会自动隐式调用 析构函数的调用次序与构造函数相反 派生类的析构函数 调用构造函数的次序 基类 对象成员 派生类 基类 对象成员 派生类 调用析构函数的次序 37 include includeclassPerson charName 10 姓名intAge 年龄public Person char name intage strcpy Name name Age age cout constructorofperson Name endl Person cout deconstrutorofperson Name endl classStudent publicPerson charClassName 10 班级PersonMonitor 班长 对象成员public Student char name intage char classname char name1 intage1 Person name age Monitor name1 age1 strcpy ClassName classname cout constructorofStudent endl Student cout deconstrucorofStudent endl intmain Studentstu 张弓长 18 计算机51 李木子 20 return0 38 include includeusingnamespacestd classStudent public Student intn stringnam num n name nam voiddisplay cout num num endl cout name name endl protected intnum stringname classStudent1 publicStudent public Student1 intn stringnam intn1 stringnam1 inta stringad Student n nam monitor n1 nam1 age a addr ad voidshow cout Thisstudentis endl display cout age age endl cout address addr endl voidshow monitor cout endl Classmonitoris endl monitor display private Studentmonitor intage stringaddr intmain Student1stud1 10010 Wang li 1001 Liu xiang 19 115BeijingRoad Shanghai stud1 show stud1 show monitor return0 39 多层派生时的构造函数 include includeusingnamespacestd classStudent public Student intn stringnam num n name nam cout constructorofStudent cout num num name name endl protected intnum stringname classStudent1 publicStudent public Student1 intn stringnam inta Student n nam age a cout constructorofStudent1 age age endl private intage classStudent2 publicStudent1 public Student2 intn stringnam inta ints Student1 n nam a score s cout constructorofStudent2 score score endl private intscore intmain Student2stud 10010 Li 17 89 return0 40 多层派生时的构造函数 续 先初始化Student的数据成员num和name再初始化Student1的数据成员age最后再初始化Student2的数据成员score有多层派生时 每一层派生类的构造函数 不需要列出其上面所有各层派生类的构造函数 只需写出直接父类的构造函数即可 41 派生类的拷贝构造函数 拷贝构造与构造函数的方式类似 派生类若自定义拷贝构造函数 则派生类对象在拷贝创建时先调用父类的拷贝构造函数 再调用派生类拷贝构造函数完成自己的拷贝 若基类没有定义拷贝构造函数 则派生类对象在拷贝创建中调用基类默认的拷贝构造函数 派生类若没有定义拷贝构造函数 则派生类对象在拷贝创建时先调用父类的默认拷贝构造函数 再调用派生类默认拷贝构造函数 42 继承与派生结构 单派生 一个基类派生出一个派生类多派生 一个基类派生出多个不同的派生类多层派生 派生类又作为基类 继续派生新的类单继承 派生类只从一个基类派生多 重 继承 派生类从多个基类派生 继承与派生结构 43 多派生 include includeusingnamespacestd classPerson protected charName 10 charSex intAge public voidRegister char name intage charsex strcpy Name name Sex sex m m f Age age voidShowMe cout 姓名 Name endl cout 性别 Sex m 男 女 endl cout 年龄 Age endl classTeacher publicPerson charDept 20 intSalary public Teacher char name intage charsex char dept intsalary voidShowMe Person ShowMe cout 工作单位 Dept endl cout 月薪 Salary endl endl Teacher Teacher char name intage charsex char dept intsalary Register name age sex strcpy Dept dept Salary salary 44 多派生 续 classStudent publicPerson charID 12 charClass 12 public Student char name intage charsex char id char classid voidShowMe cout 学号 ID endl Person ShowMe cout 班级 Class n Student Student char name intage charsex char id char classid Register name age sex strcpy ID id strcpy Class classid intmain Teacherteach1 章立早 38 m 计算机学院 2300 Studentstd1 李木子 22 f 02035003 信管01 teach1 ShowMe std1 ShowMe return0 45 单继承 Point h文件Point类的声明 ifndefPOINT H definePOINT HclassPoint intx y 点的x和y坐标public Point int 0 int 0 voidSetPoint int int 设置坐标intGetX returnx 取x坐标intGetY returny 取y坐标voidPrint 输出点的坐标 endif Point cpp文件Point类的成员函数定义 includeusingnamespacestd include point h Point Point inta intb SetPoint a b voidPoint SetPoint inta intb x a y b voidPoint Print cout x y 46 单继承 续 Circle h文件Circle类的声明 ifndefCIRCLE H defineCIRCLE H includeusingnamespacestd include point h classCircle publicPoint doubleradius public Circle intx 0 inty 0 doubler 0 0 voidSetRadius double 设置半径doubleGetRadius 取半径doubleArea 计算面积voidPrint 输出圆心坐标和半径 endif Circle cpp文件Circle类的成员函数定义 includeusingnamespacestd include circle h Circle Circle inta intb doubler Point a b SetRadius r voidCircle SetRadius doubler radius r 0 r 0 doubleCircle GetRadius returnradius doubleCircle Area return3 14159 radius radius voidCircle Print cout Center Point Print cout Radius radius endl 47 单继承 续 Example11 5 cpp文件 includeusingnamespacestd include point h include circle h intmain Pointp 30 50 Circlec 120 80 10 0 cout Pointp p Print cout nCirclec c Print cout Thecentreofcirclec c Point Print cout nTheareaofcirclec c Area endl return0 48 多继承时派生类的声明class派生类名 继承方式1基类名1 继承方式2基类名2 注意 每个继承方式 仅限制紧随其后的基类的继承 多继承的声明 49 构造函数的调用次序 调用基类构造函数 调用顺序按照它们被继承时声明的顺序 从左到右 调用对象成员的构造函数 调用顺序按照它们在类中声明的顺序 执行派生类的构造函数体 多继承的构造函数与析构函数 50 多继承 base1 h文件 ifndefBASE1 H defineBASE1 HclassBase1 intvalue public Base1 intx value x intgetData const returnvalue endif base2 h文件 ifndefBASE2 H defineBASE2 HclassBase2 charletter public Base2 charc letter c chargetData const returnletter endif 51 多继承 续 derived h文件 ifndefDERIVED H defineDERIVED H include base1 h include base2 h 多继承classDerived publicBase1 publicBase2 doublereal 派生类私有的数据成员public Derived int char double doublegetReal const voidOutput endif derived cpp文件 includeusingnamespacestd include derived h Derived Derived inti charc doublef Base1 i Base2 c real f doubleDerived getReal const returnreal voidDerived Output cout Integer Base1 getData nCharacter Base2 getData nRealnumber real endl 52 Example11 7 cpp文件多重派生 includeusingnamespacestd include base1 h include base2 h include derived h intmain Base1b1 10 base1Ptr 0 Base2b2 Z base2Ptr 0 Derivedd 7 A 3 5 对象输出各自的数据成员cout Objectb1containsinteger b1 getData nObjectb2containscharacter b2 getData nObjectdcontains n d Output 派生类对象对基类成员函数的访问cout DatamembersofDerivedcanbe accessedindividually coutgetData yields getData getData yields getData endl return0 53 赋值兼容规则 在派生类对象和基类对象之间赋值时需要注意赋值的方向 赋值操作应满足赋值兼容原则 向上兼容 基类指针可以指向派生类对象 可以把派生类对象赋值给基类对象 派生类对象可以初始化基类对象的引用 通过基类对象名 指针只能使用派生类从基类继承的成员 不能使用派生类新增的成员 54 赋值兼容规则举例 1 classA intx public voidsetX intm x m voidprintX cout x n classB publicA inty public voidsetY intm y m voidprintY cout y n voidmain Aa a setX 2 a printX Bb b setX 3 b setY 4 b printX b printY Ac b c printX 55 赋值兼容规则举例 2 includeusingnamespacestd classPet 基类 public voidSpeak cout Howdoesapetspeak endl classCat publicPet 派生类 public voidSpeak cout miao miao endl classDog publicPet 派生类 public voidSpeak cout wang wang endl intmain Petobj p1 基类对象指针p1 基类对象objDogdog1 Catcat1 obj dog1 用Dog类对象给Pet类对象赋值obj Speak p1 56 classA public inta voiddisplay classB public inta voiddisplay classC publicA publicB public inta voidshow voidmain Cc1 c1 a 3 执行哪一个 c1 display 执行哪一个 两个基类有同名成员 57 两个基类有同名成员 续 如何解决这种二义性 58 二义性问题 1 在多继承时 若基类与派生类之间 或基类之间出现同名成员 将出现访问时的二义性 不确定性 当同一个基类被同一个派生类间接继承多次的时候 将在该派生类中产生该基类的多个副本 此时访问该基类中的成员 将产生二义性 59 二义性问题 2 解决二义性的方法同名覆盖 隐藏 原则如果派生类与基类之间出现同名成员 这时系统自动用派生类的成员名覆盖 隐藏 基类成员名 派生类成员名优先 类名限定法不同基类之间出现同名成员 使用基类名来显式指定成员基类名 数据成员名基类名 成员函数名 参数表 60 classA public inta voiddisplay classB
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 1.3 带电粒子在匀强磁场中的运动 教学评大单元分课时教学设计 -2024-2025学年高二下学期物理人教版(2019)选择性必修第二册
- 食品厂质量管理制度
- 选举投票流程及注意事项教程
- 汽车销售流程管理及客户服务指南
- 高级导游考试题库及答案
- 小学三年级数学单元测试讲评方案
- 新概念英语二册课程详细教案
- 工业污水治理技术方案汇编
- 中高考备考心理辅导方案
- 建筑装饰装修工程项目管理方案
- powerbi考试题及答案
- 涉嫌强奸和解协议书
- 红字发票折让协议书
- 智慧中小学培训
- 《中国进口牛肉评估》课件
- 小学音乐人音版三年级上册维也纳的音乐钟教案
- 流产补偿协议合同
- 醉酒警情处置规范
- 关于加强医药卫生领域廉政建设的意见(2025年版)解读
- 消毒设施配置和医疗废物处理方案
- 2025年人教版九年级化学上册全册单元知识点总结汇编(全册)
评论
0/150
提交评论