版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第10章 继承、虚函数和多态性继承基础知识基类访问控制使用保护成员调用基类构造函数构造多层次结构多基类的派生类构造函数与析构函数调用顺序派生类指针虚拟函数与多态性纯虚拟函数与抽象类本章主要内容11721710.1 继承基础继承、虚函数和多态性是C+面向对象编程的特征。继承允许一个类继承另一个类的特征。使用继承就可以创建一个普通类,它定义一组相关对象的共有特征。这个类然后可以由另一个更为具体的类继承,每个类都可以增加自己所独有的元素。虚函数建立在继承基础上。虚函数支持多态性,即“一个接口多种方法”的面向对象编程原则。 在C+中被继承的类叫做基类(base class)。继承基类的类就是派生类(d
2、erived class)。因此,派生类就是基类的具体版本。派生类继承基类定义的所有成员并添加自己的独特元素。C+通过允许一个类将另一个类合并到其声明中来实现继承。具体方法就是:在声明派生类时,指定基类。 Chapter 10 Exm1作为派生类的基类并意味着不能使用基类本身。 Chapter 10 Exm2317成员访问和继承继承的普通形式如下:; / : classderviedofbodyclassbadeaccesscladdderivedclass访问属性access可以省略,否则只能为public,private和protected。不写的话继承的重要优点就是,一旦创建了定义一组对
3、象所共有属性的基类,就可以使用它创建任意数量的更为具体的派生类。每个派生类都可以精确地定义自己的特征。为private。使用public就意味着基类的所有公有成员都是派生类的公有成员。 Chapter 10 Exm2第8章中讲到经常将类成员声明为私有是为了防止未经授权的访问或修改。继承类并不能撤消私有访问权限限制。因此,即使派生类包括了基类的所有成员,它也不能访问基类中的那些私有成员。 Chapter 10 Exm310.2 基类访问控制417虽然派生类不能访问基类私有成员,但是C+提供了多种解决方案。其中一个方案就是使用受保护成员。第二个方案就是使用公有函数对私有数据进行访问。通常C+程序员
4、允许通过函数对类的私有成员进行访问。提供访问私有数据权限的函数就是存取函数(access function)。 Chapter 10 Exm4如果一个类继承另一个类,基类成员就成了派生类的成员。不过,在派生类内部是否能访问基类成员是由访问说明符确定的。继承基类时会指定访问说明符,基类访问说明符必须是public,private或protected。如果不使用访问说明符,而且派生类是class,默认情况下就是private。如果派生类是struct,那么默认值就是public。如果基类以public方式被继承,那么基类的所有公有成员都会成为派生类的公有成员。在基类的私有成员保持私有性,派生类的成
5、员不能访问基类的私有成员。 Chapter 10 Exm510.3 使用受保护的成员517与公有继承相反的就是私有继承。如果将基类继承为private,那么基类的所有公有成员都会成为派生类的私有成员。 Chapter 10 Exm6如果将基类继承为private,那么基类的公有成员就会成为派生类的私有成员,也就是说派生类的成员仍然可以访问它们,但是程序的其他部分则不能访问它们。可使用protected访问修饰符创建受保护成员。如果将类成员声明为protected,那么该成员就是私有的,只有一个例外。这个例外发生在受保护成员被继承时。在这种情况下,派生类可以访问基类的受保护成员。因此,使用pro
6、tected,就可以创建这样的类成员:它是私有的,但是派生类仍然可以访问和继承。protected说明符也可以用于结构。 Chapter 10 Exm7617如果将基类继承为公有的,那么受保护的基类成员就会变成派生类的受保护成员。如果将基类继承为私有,那么基类的受保护成员就会变成派生类的私有成员。 protected访问说明符可以出现在类声明的任何位置,不过它一般出现在声明(默认)私有成员后和声明公有成员之前。 除了为类成员指定受保护的身份外,在继承基类时也可以使用关键词protected作为访问说明符。当以受保护方式继承基类时,基类的所有公有和受保护成员都变成派生类的受保护成员。10.4 构
7、造函数和继承使用什么构造函数构建派生类的对象,使用基类中的构造函数还是使用派生类中的构造函数,或使用它们两个?答案就是:基类的构造函数构建对象的基类部分,派生类的构造函数则构建对象的派生类部分。任何一个类都有构造函数,没有定义构造函数的类,C+编译器会自动为其生成默认构造函数。在实际应用中,绝大多数类都有构造函数。如果只有派生类只有派生类定义构造函数定义构造函数,那么处理过程就会很简单:只构造派生类对象,717调用基类构造函数调用基类构造函数对象的基类部分使用其默认构造函数自动构建。 Chapter 10 Exm8基类定义构造函数时,派生类就必须显式地调用它,以初始化对象的基类部分。派生类可使
8、用派生类构造函数声明的扩展形式调用其基类定义的构造函数。该扩展声明的一殷形式如下; / )(arg : )(argrconstructoderivedofbodylistconsbaselistrconstructoderived此处的基类是指派生类所继承的基类。请注意用冒号将派生类的构造函数声明与基类构造函数分隔开(如果类继承一个以上的基类,那么用逗号将基类构造函数彼此分隔开)。 Chapter 10 Exm9派生类的构造函数可以调用基类定义的任何形式的构造函数。执行的是与参数相匹配的构造函数。 Chapter 10 Exm10817项目10-1:扩展Vehicle类 / )& (r
9、constructoofbodyobjclassnameconstclassname关键在于一旦创建了定义对象通用属性的基类,就可以继承基类形成具体化的类。每个派生类只添加自己的独特的属性。这就是继承的关键所在。 Chapter 10 Project10_110.5 创建多层层次结构由于存在继承的关系,派生类可以充分利用前面定义的类,只添加它自己需要的额外信息,以满足自己的具体应用。继承的价值在这里有所体现:它允许代码复用。该示例还说明了另一个要点。在类层次结构中,如果这类构造函数需要参数,那么所有派生类部必须向上传递那些参数,而不管派生类自己是否需要参数。 Chapter 10 Exm129
10、1710.6 继承多个基类 Chapter 10 Exm13 前述试验和结果总结如下:创建派生类的对象时,先调用基类构造函数,接下来调用派生类的构造函数。销毁派生类对象时,先调用其析构函数,然后调用基类的析构函数。换句话说,按派生顺序执行构造顾数。按与派生相反的顺序执行析构函数。在多层的类层次结构中(即派生类变成另一个派牛类的基类的情形),它们的大体原则都一样:按派生顺序调用构造函数,按相反的顺序调用析构函数。如果类同时继承一个以上的基类,就会按派生类继承列表中所指定的顺序从左到右调用构造函数。调用析构函数则按从右到左的顺序进行。10.7 构造函数和析构函数执行的顺序 Chapter 10 E
11、xm14101710.8 指向派生类型的指针基类指针和派牛类指针之间有一种其他类型的指针不具备的关系。总体上讲,一种类型的指针不能指向另一种类型的对象。不过,这条规则不适用于基类指针和派生对象。在C+中。基类指针也可用于指向从该基类派生而来的任何派生类的对象。 Chapter 10 Exm15基类指针只能用于访问派生对象从基类继承而来的那些成员。要理解的另一点就是:虽然基类指针可以指向派生对象,但相反的做法是不成立的。也就是说,不能使用派生类指例访问基类类型的对象。指针是根据其基类类型增减的。因此,如果基类指针指向派生对象,对它进行增减运算就不会让它指向派生类的下一个对象。与此相反,它将指向它
12、所认为的基类的下一个对象。因此,应该认为在基类指针指向派生对象时,增减它的值是无效的。111710.9 虚函数和多态性基类指针可以用于指向由该基类派生而来的任何对象,这对C+相当重要,也是其基本所在。这种灵活性对于C+实现运行时多态性的方式是很重要的。C+支持多态性的基础由继承和基类指针组成。实际实现多态性的具体功能就是虚拟函数。一、虚函数基础知识虚函数(virtual function)在基类中声明为virtual,并在一个或多个派生类中重新定义。因此,每个派生类都可以有它们自己的虚函数版本。当使用基类指针调用虚函数时会发生一些有对派生类型的引用对派生类型的引用与刚才介绍的指引的动作相似,可
13、以使用基类引用来引用派生类型的对象。最常见的应用就是应用于函数参数。基类引用参数可以接收基类的对象以及从该基类派生而来的任何其他类型的对象。1217趣的现象。当调用时,C+会根据指针指向的对象的类型确定调用函数的哪个版本。这是在运行时做出的决定。因此,如果指向不同的对象,多态性就会执行不向的虚函数版本。换句话说,由指针指向的对象类型(而不是指针类型)来确定执行哪个虚函数版本。因此,如果基类包含虑函数且有两个或多个类由基类派生而来,那么当通过基类指针指向不同类型的对象时,就会执行不同版本的虚函数。 在声明前面加上关键字virtual,就可以在基类内部将一个函数声明为虚函数*派生类重新定义虚函数时
14、,不需要重复使用关键字virtual(虽然这样做也不是错误)。 包括虚拟函数的类被称为多态类(polymorphic class)。该术语也适用于继承包含虚函数基类的派生类。 Chapter 10 Exm15起初,在派生类中重新定义虚函数好象是函数重载的特殊形式。不过,事实并非如此。实际上,这两个过程本质上并不相同。1317首先,重载函数必须在参数的数量和/或类型上不同,但是重定义虚函数必须有完全相同的参数类型和数量。事实上,虚函数的原型和其重新定义必须完全相同。如果原型不同,那么此函数只是重裁,而失去了其虚拟的本质。另一个限制条件就是虚函数必须是定义它的类的成员而不是友元。不过,虚函数可以是
15、另一个类的友元。另外,允许把析构函数定义为虚函数,但构造函数不能。由于重载标准函数和重新定义虚函数之间的差别和限制,所以用覆盖(overriding)这个词来描述虚函数的重定义过程。二、继承虚函数一旦将函数声明为虚函数,不管它通过多少层派生类,它都是虚函数。 Chapter 10 Exm16请记住虚函数虚拟特性是以层次结构的方式来继承的。1417三、使用虚函数的原因综上所述,与派生类型联合使用的虚函数允许C+支持运行时多态性。多态性是面向对象编程的基本功能,因为它允许一般化的类指定类的所有派生类共用的那些函数,同时允许派生类定义所有这些函数或其中一部分函数的具体实现。有时也这样描述这个思想:基
16、类规定任何派生类对象所共有的一个接口,让派生类定义用于实现该接口的实际方法。这就是为什么经常使用短语“一个接口多种入池”来描述多态性的原因。要成功应用多态性,就要理解基类和派生类形成一个层次结构,其普遍性从大到小(从基类到派生类)。如果设计正确,基类就会提供派生类可以直接使用的所有元素,它也定义派生类必须自己实现的那些函数。这就允许派生类灵活定义其自己的方法,同时仍保持一致的接口。也就是说,由于基类定义接口形式,任何派生类都会共享这个共同的接口。因此,使用虚阁数就能让基类定义一个所有派生类都会使用的通用接口。这时,您可能会问为什么说多个实现使用一致的接口很重1517要。要找到答案就要回到面向对
17、象的编程背后的核心驱动力量上来:它有助于程序员处理日益复杂的程序。例如,如果开发程序的方法正确,就知道从基类派生来的所有对象都可以使用相同的方式来访问,即使具体操作会随派生类的不同而不同。这就是说只需要处理一个接口,而不是多个接口。派生类还可以自由使用基类提供的所有功能或任何功能,不需要重新创建这些元素。 接口和实现之间的分离也允许创建类库(class libraries),类库可以由第三方提供。如果正确实现这些库,它们将提供公用的接口,使用这个公有接口就可以派生出自己的类,以满足特定的需要。例如,微软基础类(MFC)和更新的.NET Framework Windows Forms类库都支持W
18、indows编程。通过使用这些类,程序就可以继承Windows程序所要求的许多功能。只需要添加应用程序特有的功能。这就是编写复杂系统的主要益处。161710.10 应用虚函数 Chapter 10 Exm1710.11 纯虚函数和抽象类有时创建基类,就只定义与其所有派生类共享的一般形式,并由每个派生类来填充其详细信息。这样的类确定派生类必须实现的函数的特性,而它自己却不提供实现一个或多个这些函数的方案。基类不能创建有意义的函数实现时,就会出现这种情形。创建自己的类库时就会发现,函数不能在基类环境中提供有意义的定义的情况并不少见。可以采用两种方法处理这种情况。一种方法如上面的示例所示,只报告警告消息。虽然这种方法在某些场合下很有用(如调试),但通常都不合适。有些函数必须由派生类覆盖,派生类才能有意义。这种情况需要以某种方式来确保派生类覆盖所有必要的函数。C+解决这个问题的方案就是
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年触电应急救援试题(含答案)
- 2025下半年小学教资笔试真题+参考答案(科目一+科目二)
- 2026事业单位工勤技能-新疆-新疆殡葬服务工二级(技师)历年参考题库含答案详解
- 2026事业单位工勤技能-广西-广西环境监测工三级(高级工)历年参考题库含答案详解
- 2026事业单位工勤技能-广东-广东殡葬服务工二级(技师)历年参考题库含答案详解
- 小型企业用人合同(范本)
- 2026事业单位工勤技能-山西-山西垃圾清扫与处理工三级(高级工)历年参考题库含答案详解
- 2026事业单位工勤技能-山东-山东有线广播电视机务员二级(技师)历年参考题库含答案详解
- 2026事业单位工勤技能-天津-天津热处理工二级(技师)历年参考题库含答案详解
- 2026事业单位工勤技能-四川-四川水工监测工三级(高级工)历年参考题库含答案详解
- 2026年秋季襄阳东津新区中小学教师公开招聘100人考试参考题库及答案详解
- 2026 年大学新生入学第一课宿舍财物防盗安全防范意识教育
- 2026年陕西高职单招试题完整
- 2026中国公证协会招聘5人笔试题库(夺冠)附答案详解
- 2026年中级经济法担保法律制度专项题库(含答案及解析)
- 2.2站稳人民立场( 教学设计) 统编版道德与法治 九年级上传(新)
- 2026年企业安全生产事故隐患排查治理制度实施指南与案例
- 国新基金校招面经笔试试题题库
- 客户健康风险评估预案
- (2026版)《低分子肝素临床应用中国专家共识2026》解读课件
- 眼科急症的识别与处理流程
评论
0/150
提交评论