ImageVerifierCode 换一换
格式:PPT , 页数:146 ,大小:1.44MB ,
资源ID:1759202      下载积分:15 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/1759202.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(C程序设计语言(李雁妮)第11章.ppt)为本站会员(b****1)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

C程序设计语言(李雁妮)第11章.ppt

1、第11章 继承与多态,11.1 概述11.2 子类/派生类11.3 虚函数与多态性*11.4 运行时的类型识别*11.5 指向类成员的指针11.6 多重继承11.7 综合示例小结练习题,本章要点:子类/派生类和继承的基本概念;子类对象的存储结构;子类中的成员;C+的三种继承方式;虚函数和多态;运行时的类型识别,RTTI机制;多重继承。,11.1 概 述按照面向对象的理念,在第9章曾经给出过这样一个断言:当某个概念用语言的基本类型不能具体表示时,就应当定义一个新的类型。由于现实中每个概念不是孤立存在的,它总是和一些相关的概念共同存在,并且可从相关的概念中导出更大的能量,因此,当某个概念与其它概念

2、之间存在着共性关系时,应当在相应的类型之间也表示出这样的关系,这正是面向对象的精粹所在。孤立类只能描述实体集合特征的同一性,而客观世界中实体集合的划分通常还要考虑实体特征方面有关联的相似性。,“相似”无非是既有共同点,又有差别。相似性有两种类别。(1)内涵的相似性:概念之间具有一般与特殊的关系,它们之间存在着共性。例如雇员(Employee)与经理(Manager)之间的关系就属于此类,一个Manager是一个Employee,而且是一个特殊的Employee。(2)结构的相似性:概念之间具有相似的结构表示。例如数组类array和vector,虽然vector是一种特殊的动态数组,但其结构与a

3、rray相同。那么,如何利用语言中相应的机制来表示这种相似性呢?,(1)如果将相似的事物用不同的类型来表示,则只能够表示其差别,体现不了它们之间存在着共性这一事实;另外,在不同的类中其共性的表示也可能不一致,当扩充维护过程中需要对其共性部分进行修改时,就面临着保持一致性的问题。(2)如果将相似的事物用相同的类型来表示(例如把可能的特征都定义上去,再设法进行投影),则体现其差别就十分困难,且失去了类型化的支持。一旦需扩充和修改(哪怕只是涉及差别部分),也将影响用此种类型表示的所有其它事物。,显然上述两种做法都不能较准确地表达类型之间的相似关系。C+提供的继承机制可供我们方便地表达类之间的共性。本

4、章将要讨论面向对象程序设计中两个极为重要的机制:继承(Inheritance)和多态(Polymorphism)。面向对象程序设计的关键之一就是通过继承来实现软件的重用(Reuse),通过多态来实现软件的自适应性和灵活性。,11.2 子类/派生类11.2.1 子类/派生类与继承的基本概念首先,让我们从一实际问题出发,来看一看如何正确地表达两个概念(雇员类Employee与经理类Manager)之间的相似性。方式1 将相似的事物用不同的类型表示,但类中重复定义共同的特征。,(注意:两个类中阴影部分是相同的。)类Manager除了具有和Employee相同的属性外,还拥有它自己的属性:所管理的雇员

5、列表list group和它的级别short level。方式2 将相似的事物用不同的类型来表示,类中将共同的特征归纳成一个抽象特征对象成员来表示。,上述两种共性的表示方式对读者特别是细心的读者来讲一目了然,但这种共性关系对编译器和运行环境而言却一无所知!由于用了两个(没有指明存在共性关系的)类型(类Employee和Manager)来表示它们之间的共性关系,因此一个Manager*不是一个Employee*。所以,一个Manager*不仅不能用于Employee*出现的场合,而且对于上述的应用而言,Manager*根本插入不到经理类Manager所管理的雇员列表group对象中。,C+的派生

6、类机制通过定义Manager是从Employee继承而来的,从而显式地定义了两者之间的共性。继承机制明确表明:一个Manager就是一个Employee,其差异在于一个Manager是一个特殊的Employee。class Manager:public Employee/类Manager自Employee继承而来 list group;short level;/.;,上述定义中,Manager称为基类(Base Class)或父类(Superclass),相应地,Employee称为派生类(Derived Class)或子类(Subclass)。类Manager不仅继承了类Employee的所

7、有成员(所继承的成员无须在子类中定义),而且拥有它自己的成员list group和short level。通常,把一个派生类自它的父类继承(Inherit)而来这种继承关系称为继承性(Inheritance),如图11.1所示。,图11.1 类Employee和Manager之间的继承关系,注意:与我们常规理念不同的是,派生类通常大于父类。一个子类不仅继承了其父类的所有数据成员与方法,而且还拥有它自身的数据成员与方法,因此,子类与父类之间满足:sizeof()sizeof(),11.2.2 子类对象的存储结构子类/派生类对象的存储结构与父类/基类对象的存储结构存在着“粘接”关系,即子类对象的存

8、储结构是其父类对象成员粘接上自己的数据成员,其“粘接”关系如图11.2所示。子类与父类之间的关系实际上是一种“是一”(is_a)关系,即子类是一个父类,如图11.3所示。由于父类与子类之间为“是一”关系,因此,一个子类对象一定是一个父类对象。指向父类的指针和引用可用于子类指针和引用出现的场合,但其逆命题不成立。,图11.2 子类对象与父类对象之间存储结构的粘接性,图11.3 子类与父类之间的“是一”关系,11.2.3 子类中的成员当类Manager 继承Employee时,目的除了要表示它们之间的相似关系以外,更重要的是让 Manager的操作集利用继承关系的描述而自然地发生扩张。对Emplo

9、yee数据结构的继承只是手段而不是目的。利用继承机制达到了子类Manager操作集的自然扩张,以及对其操作集的使用不需要了解父类Employee 操作集的细节。例如:,根据上述定义,类Manager是Employee的子类,因此,Manager继承了父类Employee的所有成员(构造函数与析构函数除外)。Manager类的数据成员是:,11.2.4 子类的构造与析构函数由于子类继承了父类的数据成员和方法,因此,子类的实例生成和消除与父类的实例生成和消除自然相关。一个子类对象的构造过程是:先构造其父类对象,然后再构造自己。其析构过程与构造过程相反,即先析构自己,然后再析构父类对象。因此,子类的

10、构造函数参数表中的参数应包含两部分:调用基类的对应构造函数所需的参数;子类构造函数所需的参数。,子类对象在析构时,子类的析构函数会自动调用基类的析构函数。C+语法规定:在子类中对父类构造函数的调用只能通过初始化表的方式进行。例如:class Employee string first_name,family_name;char middle_initial;short department;/.public:void print()const;string full_name()const;,总之,子类对象的构造是自顶向下的,即首先构造父类对象,然后构造子类中的对象成员,最后构造子类本身;其对

11、象的析构次序与构造次序相反,即首先析构子类对象,然后析构子类中的对象成员,最后析构基类对象。在一个类中可能有多个对象成员,另外类层次亦可能为多层,此时,对象成员和基类的构造次序与它们声明的次序相同,析构时与其声明的次序相反。对象的构造与析构次序如下例所示:,11.2.5 子类对象拷贝通过前面的学习我们已经知道:当一个类自另一个类继承而来时,子类和父类之间就存在着“是一”关系,即一个子类对象亦是一个父类对象,但其逆命题不成立。因此,子类对象可以赋值或拷贝给父类对象,但此时仅将子类对象中相应的父类对象值部分赋值或拷贝给父类对象。例如:,11.2.6 public、protected和private

12、继承C+中提供了三种继承父类的方式,即:公有继承(public);保护继承(protected);私有继承(private,C+中缺省的继承方式)。一般常用公有继承,保护继承和私有继承只在一些特殊的场合中使用。类的每个成员都具有访问控制权限,在第9章中已经指出访问控制的作用是:使得类的成员函数确实构成了这个类的操作集;,易于进行出错定位;用成员函数的声明组成这个类的接口;有利于掌握一个类型的使用方式。具有各种访问控制的成员对外所具有的能见度如图11.4所示。由于有了继承机制,类成员的访问控制就涉及派生类以不同方式从基类继承的、具有不同能见度的那些成员。关于派生类有怎样的外部能见度与内部能见度问

13、题,下面我们就不同的继承情况分别进行讨论。,图11.4 具有各种访问控制的成员的对外能见度,1public公有继承class B:public A/.;当公有继承时,子类B从父类A中继承下来的所有成员的访问权限不变。对类B而言,其内部能见度为父类的protected、public成员,以及自己的具有各种访问控制的所有成员;类B的外部能见度为父类的public成员及自身的public成员。B类所继承的父类的protected成员及自身的protected成员只对B类的子类可见。,2protected保护继承class B:protected A/.;当保护继承时,子类B从父类A中继承下来的pri

14、vate及protected成员的访问权限不变,但父类的public变为protected。对类B而言,其内部能见度为父类的protected、public成员,以及自己的具有各种访问控制的所有成员;类B的外部能见度仅为自身的public成员。B类所继承的protected、public(已改变为protected)及自身的protected成员只对B类的子类可见。,3private公有继承class B:private A/私有继承,C+规定可缺省/.;当私有继承时,子类B将父类A中继承下来的protected及public成员的访问权限全部改为private。对类B而言,其内部能见度为父类

15、的protected、public成员,以及自己的所有成员;类B的外部能见度仅为自身的public成员。类B的protected成员只对其子类可见。表11.1总结了在不同的继承下,基类成员访问控制的变化情况及子类对基类成员的内、外能见度。,由于C+有三种继承方式,所以子类的内、外能见度同时与继承方式和被继承者的能见度相关。,11.3 虚函数与多态性11.3.1 类型域当采用指针或引用时,一个子类对象可以被当作一个父类对象使用。当某一函数接口参数的类型为父类型的指针或引用时,由于其实参可为父类或其子类的指针或引用,因此操作时常常需要对传入的实参对象的类型进行判断。例如:void print_em

16、ployee(const Employee*e)if(*e的类型是Employee)/打印Employee对象的信息 else,if(*e的类型是Manager)/打印Manager对象的信息 else/.在上述打印雇员信息的函数print_employee中,由于参数是Employee*类型,因此它可以接受Employee或Manager对象的地址,故在函数体中应对实参传入的对象类型作出判断,之后进行相应的处理。为实现正确的操作,要求对象本身带有类型信息。,使对象带有类型信息的方法是在对象所属的类中设立类型标志信息。仍以Employee和Manager类为例,此时,在Employee类中定义一个标识所属类别的类型域成员type(枚举类型的变量),然后对Employee和Manager对象在其成员上赋相应的值,使对象自身带有类型信息。例如:,在类定义中采用类型域的方法是不应当提倡的,因为编译程序无法检查出诸如将 Employee:M 赋给 Employee:type 这样的错误。另外,编译程序亦无法检查出未在所有的构造函数中将类型域变量都赋同样的、正确的值的错误。对于大型软件,人工保持

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1