visual studio学习第10章 继承与多态性

上传人:zw****58 文档编号:51595512 上传时间:2018-08-15 格式:PPTX 页数:22 大小:147.80KB
返回 下载 相关 举报
visual studio学习第10章  继承与多态性_第1页
第1页 / 共22页
visual studio学习第10章  继承与多态性_第2页
第2页 / 共22页
visual studio学习第10章  继承与多态性_第3页
第3页 / 共22页
visual studio学习第10章  继承与多态性_第4页
第4页 / 共22页
visual studio学习第10章  继承与多态性_第5页
第5页 / 共22页
点击查看更多>>
资源描述

《visual studio学习第10章 继承与多态性》由会员分享,可在线阅读,更多相关《visual studio学习第10章 继承与多态性(22页珍藏版)》请在金锄头文库上搜索。

1、第第1010章章 继承与多态性继承与多态性本章将介绍面向对象编程中两个非常重要的概念继承和多态。继承 是C+语言中类机制的一部分,该机制使类与类之间可以建立一种上下级关 系。继承是一种手段,利用继承机制,可以根据另一个类的操作和数据成员 来创建新类。多态性是在继承的基础上实现,它可以实现一个方法有不同的 操作。 l 类的继承层次关系 l 派生类对象的结构 l 派生类的访问控制 l 派生类的构造、析构和复制函数 l 相关类类型之间的转换 l 多态性 l 虚函数和抽象类 l C+/CLI装箱与拆箱 l 在C+/CLI中的继承机制 l C+/CLI接口类 l C+/CLI中的委托和事件10.1 10

2、.1 继承的基本概念继承的基本概念类是C+中提供封装的逻辑单位,它封装了变量和函数。同时, C+还提供了继承机制,通过继承,过去的代码就不需要丢弃,只需要经 过稍加修改后就重用。在人类文明的发展中,现在的文明就是建立其先 人文明的基础上,事实上,事物的发展都是从建立其先前的基础上的。 类的继承就反映了从先前简单代码发展到丰富的高级代码的过程。10.1.1 10.1.1 类的层次关系类的层次关系利用继承性,可以在已有类的基础上构造新类,这一性质使得类与类之间可 以建立一种上下级的分类关系。继承关系使得我们可以用一种简单的方式来描述事物。例如,描述什么是鹰 ,可以描述为一种大型的食肉鸟类。鹰是一种

3、鸟,所以鹰是鸟类的派生,但鹰又 具有自己的特征,大型的以食肉为主的特征是它区别于其他鸟类的属性。由于鸟 类通常的特征大家都知道,如,有翅膀,有两个脚等,所以用鸟类来描述鹰,只 要列举出它自己的所具有特点即可。描述事物一般是从属性和操作上来描述的,例如,日期具有年、月、日的 属性,显示日期,判断某年是否为闰年的操作。继承就是让子类继承父类的属性 和操作,子类可以声明新的属性和操作,还可以替换哪些不适合其用途的父类操 作。在新的应用中,父类的代码已经存在,无须修改,所要做的就是派生子类类 ,并在子类中添加和修改。所以继承可以重用父类的代码,提高代码的利用率。继承也是我们理解事物、解决问题的方法,继

4、承帮助我们描述事物的层次 关系,有效而精确地描述事物,理解事物直至本质。一旦看清了事物所处的层次 关系,也就可以找到相关的解决办法。10.1.2 10.1.2 派生类对象的结构派生类对象的结构如果类BaseClass是父类:class BaseClassprivate:int a,b;/私有成员public:/公有成员;该类对象包含了两个整型数据成员所占用的内存空间。在该父类上派生子类的方 式是在子类名后添加public关键字和父类名。如SubClass继承的BaseClass类,则:class SubClass : public BaseClassprivate:int c;/私有成员pub

5、lic:/公有成员;子类SubClass的对象包含两部分:一部分为父类部分,即两个整型数据成员所 占用的,空间;另一部分为子类新添加的整数空间。10.2 10.2 继承机制下的访问控制继承机制下的访问控制在继承机制下,类的访问控制符又有了新 的意义。例如,对于父类的私有成员,在子类中 是否可以直接访问?本节将对介绍父类中的访问 控制对子类的影响。l 访问父类成员l 继承方式10.2.1 10.2.1 访问父类成员访问父类成员如果将基类中的数据成员变为私有的 private,则上面的程序将无法编译,并提示 无法访问Person类的private成员。也就是说 ,子类不能访问基类的private成

6、员。原因在 于虽然基类的private成员也中派生类的成员 ,但它们在派生类中仍然为基类所私有的, 因此在派生类中不能访问基类的private成 员。如果需要在派生类中访问基类的private 成员,只能通过访问基类的public成员实现。10.2.2 10.2.2 继承方式继承方式继承可以是公有继承,也可以是保护继承和私有继 承。多数情况下,类的继承是公有的,就像前面所看到 的。也就是在子类名后使用public访问控制符限定基类 名。如果将子类名和基类名之间的public关键字替换为 private或protected,则继承就变为私有继承和保护继承。公有继承反映了派生类对基类使用的方式全部

7、接受, 在此基础之上进行扩充,以便能被外界更广泛地使用。因 此,通过派生类对象仍然可以使用基类中原来公有的操 作。派生类不能获取基类私有成员的访问权限。除此之外 ,公有继承将基类的保护成员或公有成员视为自己的保护 和公有成员。10.3 10.3 派生类的构造函数派生类的构造函数类的构造函数作为类的一种特殊成员函数,它们不 会被派生类继承,仍然存在于基类中,并且用于创建派生 类对象中基类对象部分。因为创建派生类对象的基类部分 实际上属于基类构造函数,而非派生类构造函数的任务。 如前面,基类的私有成员在派生类中虽然会被继承,但是 不可访问,因此这些任务必须交给基类的构造函数来完 成。根据类机制,如

8、果没有定义构造函数,将会执行默认 的无参构造函数。对于派生类而言,派生类的默认无参数 构造函数会首先调用父类的默认无参构造函数。如果在基 类中提供了有参数的构造函数,并且没有重载默认的构造 函数,则派生类的默认构造函数将无法正常工作。为了解 决这个问题,可以自定义派生类的构造函数,并在派生类 的构造函数中调用基类的构造函数。10.4 10.4 派生类的析构函数派生类的析构函数在派生类对象超出作用域时,或者要删除堆内存中的对 象时,总是要涉及到派生类的析构函数和基类的析构函数。 与构造函数一样,析构函数也不能被继承,在派生类中需要 自行声明。下面为Person类和Employee添加析构函数,并

9、跟踪何 时调用这两个析构函数:Person:Person() cout“Person 析构函数“endl;Employee:Employee() cout“Employee析构函数姓名: “GetName()endl;10.5 10.5 派生类的复制构造函数派生类的复制构造函数复制构造函数是使用一个已有对象创建同类对象时被自动调 用。如下面的两条语句:Person aPerson(“刘丽“,“1979-10-23“);Person copyPerson(aPerson);第一条语句调用构造函数创建Person类对象,第二条语句则 调用复制构造函数创建Person类对象。如果不提供自定义的复制

10、构造函数,则编译器会自动提供一个默认的复制构造函数,将初始 化对象成员逐一复制到新对象对应的成员中。 为了解复制构造函数的工作过程,可以给Person类添加自动定义 的复制构造函数,然后为派生类Employee添加自定义构造函数。10.6 10.6 多重继承多重继承在有些时候,我们还需要多重继承,即一个派生类有两 个以上的直接基类。例如,人类都不是单亲繁殖的,一个人 总是从他母亲和父亲两个方面继承。多重继承的使用并不多见,在Java、C#等编程语言甚 至没有多重继承,因此这里也不深入介析,只是简单说明多 重继承基本工作源理。多重继承涉及到到用两个或多个直接基类来派生一个新 类,它要比单一继承要

11、复杂的多。多重继承意味着将多个基 类的特性加在一起,形成一个包含所有基类功能的合成对 象。这通常比较便于实现,而不便于反映对象之间的关系。10.7 10.7 在相关的类类型之间转换在相关的类类型之间转换每个派生类对象都至少包含一个基类对象,把派生类型 转换为基类类型是合法的。在类层次结构中,向上的转换是合法的,反之,向下的 转换则是不合理的。也就是说,只能用子类对象向其基类对 象赋值,而不能用基类对象向其派生类对象赋值。因为基类 对象不包含派生类的成员,无法对派生类的成员赋值。同样 ,同一基类的不同子类之间也不能赋值。10.6 10.6 理解多态性理解多态性多态性是面向对象程序设计的重要特征之

12、一。它与前 面介绍的封装性、继承构成了面向对象程序设计的三大特 征。这三个特征是相互关联的,封装性是基础、继承是关键 ,多态性是补充,而多态是通过继承来实现的。所谓多态性是指同样的消息被不同类型的对象接收时, 各类型的对象会采用完全不同的行为。这里所说的消息主要 是指对类成员的调用。也就是说,不同功能的函数可以使用 同一个函数名,这样就可以用一个函数调用不同内容的函 数。从系统实现的角度看,多态性分为两类:静态多态性和 动态多态性。10.6.1 10.6.1 虚函数虚函数虚函数的作用是允许在派生类中重新定义与基 类同名的函数,并且可以通过基类指针或引用来访问 基类和派生类中的同名函数。在C+中

13、规定,当一个成员函数被声明为虚函数 后,其派生类中的同名函数都自动成为虚函数。因此 ,在声明派生类的虚函数时,可以添加virtual关键字, 也可以不添加。如果在派生类中没有对基类的虚函数 重新定义,则派生类将直接继承基类中的虚函数。虚函数实现的动态多态性是一个极为强在的机 制。在交互式应用程序中,常常不能事先确定要处理 哪种类型的对象,即在设计或编译期间不能确定类型 ,只能在运行期间确定。10.6.2 10.6.2 使用虚函数的原则使用虚函数的原则使用虚函数时应注意几点:1函数的签名和返回类型在派生类和基类中声明、定义虚函数时,函数的名称和参数列表必须相 同。一般情况下,在派生类中的返回类型

14、也必须与基类相同,但当基类中的 返回类型是类类型的指针或引用时例外。2虚函数和类层结构虚函数的作用是允许在派生类中对基类的虚函数重新定义,它只能 用于类的继承层次结构中。在基类中可以声明任意多个虚函数,但在有 若干层的类层次结构中,各层的类都可以添加属于自己特有的虚函数。3访问修饰符与虚函数虚函数在派生类中声明时,所用的访问修饰符可以不同于其在基类中声明时的访问修饰符。 在通过指针调用虚函数时,基类中的访问修饰符将确定该函数是否可以在派生类中访问。如果虚 函数在基类中声明为public,则无论它在派生类中的访问修饰符是什么,都可以通过基类的指针或 引用为所有派生类调用该函数。10.9 10.9

15、 纯虚函数和抽象类纯虚函数和抽象类有时在基类中将某一个成员函数定义为虚函数,并不是 该基类本身的需要,而是考虑到派生类的需要,在基类为中 预留一个函数名,函数的具体功能由派生类根据需要定义。纯虚函数的主要作用是允许函数的派生类版本进行多态 性的调用。要把函数声明为纯虚函数与声明一般虚函数相同 ,但在类的声明中要添加“=0”。纯虚函数通常没有实现代 码。10.9.110.9.110.9.110.9.1 纯虚函数纯虚函数纯虚函数纯虚函数10.9.2 10.9.2 抽象类抽象类抽象类是包含纯虚函数的类。因为纯虚函数是不能被调 用的,包含纯虚函数的类是无法建立对象的。抽象类的作用 是作为一个类族的共同

16、基类,即为一个类族提供一个公共接 口。抽象类可以拥用数据成员和函数成员,判断抽象类的唯 一条件是类中是否包含纯虚函数。抽象类中以包含多个纯虚 函数,这种情况下,派生的子类必须给出每个纯虚函数的定 义,否则该派生类仍然是抽象类。10.10 C+/CLI10.10 C+/CLI的应用的应用在C+/CLI中,默认情况下用户自定义的类都是派生类 ,因为数值类和引用类都是以System:Object为基类的。这 意味着数值类和引用类都继承于System:Object类,具有 System:Object类的功能。System:Object类的ToString()函 数被定义为虚函数,在自己的类中重写该函数,并在需要时 多态地调用该函数。10.10.1 10.10.1 装箱与拆箱装箱与拆箱基类System:Object还负责实现基本类型数值的装箱 (boxing)

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 教育学

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号