清华c--语言程序设计:第15章-多态性

上传人:命****币 文档编号:112804855 上传时间:2019-11-07 格式:PPT 页数:35 大小:170.54KB
返回 下载 相关 举报
清华c--语言程序设计:第15章-多态性_第1页
第1页 / 共35页
清华c--语言程序设计:第15章-多态性_第2页
第2页 / 共35页
清华c--语言程序设计:第15章-多态性_第3页
第3页 / 共35页
清华c--语言程序设计:第15章-多态性_第4页
第4页 / 共35页
清华c--语言程序设计:第15章-多态性_第5页
第5页 / 共35页
点击查看更多>>
资源描述

《清华c--语言程序设计:第15章-多态性》由会员分享,可在线阅读,更多相关《清华c--语言程序设计:第15章-多态性(35页珍藏版)》请在金锄头文库上搜索。

1、第15章 多态性,讲授内容,静态绑定和动态绑定的概念 多态性的意义和作用 虚函数的定义方法 抽象基类的作用和定义方法 虚析构函数的作用和使用方法 如何在程序中实现多态性,15.1 多态性的概念(1/5),多态性:具有继承关系的类,其对象对同一个函数调用可以作出不同的响应 同一个函数调用同一条函数调用语句 不同的响应执行不同的函数,15.1 多态性的概念(2/5),静态绑定和动态绑定 静态绑定编译时就能确定一条函数调用语句要调用的函数 和面向对象的思想不太相符 一条指令对应不同对象的不同操作现实需要,15.1 多态性的概念(3/5),静态绑定和动态绑定 动态绑定:运行时才能确定函数调用语句调用的

2、函数 调用对象的成员函数时(通过引用或指针),编译器暂不确定要调用的函数 编译器检查被调用函数是否存在(函数名、参数列表、返回值) 程序运行时,系统根据接收消息的对象类型来确定要调用的函数,15.1 多态性的概念(4/5),多态性的实现 通过基类指针或引用调用虚函数 动态绑定 多态性有助于更好地对程序进行抽象 控制模块能专注于一般性问题的处理 具体的操作交给具体的对象去做,15.1 多态性的概念(5/5),多态性有助于提高程序的可扩展性 可以把控制模块与被操作的对象分开 可以添加已定义类的新对象,并能管理该对象 可以添加新类(已有类的派生类)的新对象,并能管理该对象 常用的程序设计方法 为具有

3、继承关系的类定义接口(虚函数) 用链表或数组组织所有对象 用基类指针操作这些对象,15.2 虚函数,虚函数的定义 在函数原型前加上关键字virtual 如果一个函数在基类中被声明为虚函数,则他在所有派生类中都是虚函数(包括重定义函数) virtual void show(); 只有通过基类指针或引用调用虚函数才能引发动态绑定,例子1:虚函数与多态性例子(1/3),/文件base.h /定义基类 #if !defined _BASE_H_ #define _BASE_H_ #include class Base public: virtual void show() cout“I am Base

4、s object!n“; ; #endif,例子1:虚函数与多态性例子(2/3),/文件derived.h /定义基类Derived #if !defined _DERIVED_H_ #define _DERIVED_H_ #include “base.h“ class Derived :public Base public: void show() cout“I am Deriveds object!n“; ; #endif,例子1:虚函数与多态性例子(3/3),/文件ex15_2.cpp /测试多重继承的类层次 #include “derived.h“ main() Base *bPtr,

5、 bObj; Derived dObj; bPtr= ,程序运行如果,I am Bases object! I am Deriveds object!,15.3 抽象基类和纯虚函数(1/4),实现多态性的前提 需要有共同的基类 需要在基类中定义共同的接口 接口要定义为虚函数 如果基类的接口没办法实现怎么办? 如形状类Shape,15.3 抽象基类和纯虚函数(2/4),解决方法 不实现这些接口:纯虚函数 包含纯虚函数的类:抽象基类 抽象基类不能实例化对象 形状类Shape的对象是什么?,15.3 抽象基类和纯虚函数(3/4),纯虚函数 没有函数体的“初始化为0”的函数 /纯虚函数 virtual

6、 double area() const = 0; 纯虚函数不需要实现,15.3 抽象基类和纯虚函数(4/4),抽象类和具体类 包含纯虚函数的类不能实例化对象,是抽象类 如果抽象类的派生类实现了所有基类中的纯虚函数,则不再是抽象类 抽象类存在的意义是作为其它类的基类,也叫抽象基类,例子2:抽象基类的例子(1/6),/文件shape.h /定义抽象基类Shape #if !defined _SHAPE_H_ #define _SHAPE_H_ #include class Shape public: virtual double area() const = 0; virtual void sh

7、ow() const = 0; ; #endif,例子2:抽象基类的例子(2/6),/文件circle.h,定义派生类Circle #if !defined _CIRCLE_H_ #define _CIRCLE_H_ #include “shape.h“ #define PI 3.1416 class Circle :public Shape public: Circle(double = 0.0, double = 0.0, double = 1.0); double area() const; void show() const; private: double x,y; double r

8、; ; #endif,例子2:抽象基类的例子(3/6),/文件circle.cpp,实现类Circle #include “circle.h“ Circle:Circle(double a, double b, double c) x = a; y = b; r = c; double Circle:area() const return PI*r*r; void Circle:show() const cout“I am a Circle: “; ,例子2:抽象基类的例子(4/6),/文件rectangle.h /定义派生类Rectangle #if !defined _RECTANGLE_

9、H_ #define _RECTANGLE_H_ #include “shape.h“ class Rectangle :public Shape public: Rectangle(double = 1.0, double = 1.0); double area() const; void show() const; private: double length; double width; ; #endif,例子2:抽象基类的例子(5/6),/文件rectangle.cpp,实现类Rectangle #include “rectangle.h“ Rectangle:Rectangle(do

10、uble a, double b) length = a; width = b; double Rectangle:area() const return length*width; void Rectangle:show() const cout“ I am a Rectangle: “; ,例子2:抽象基类的例子(6/6),/文件ex15_3.cpp,测试类Shape的层次结构 #include “circle.h“ #include “rectangle.h“ void callArea(Shape ,程序运行结果,I am a Circle: area = 19.635 I am a

11、Rectangle: area = 12.72,15.4 虚析构函数,构造函数的执行顺序:从上到下 析构函数的执行顺序:从下到上 创建对象时要执行正确的构造函数 撤销对象时要执行正确的析构函数 问题:动态对象的创建和撤销,15.4 虚析构函数,动态对象的创建 动态创建的对象没有问题 new ClassName(); ClassName指明了要调用的构造函数 动态对象的撤销 delete 基类指针; 如果基类指针指向的是派生类的对象呢?,15.4 虚析构函数,析构函数可以声明为虚函数 delete 基类指针; 程序会根据基类指针指向的对象的类型确定要调用的析构函数 基类的析构函数为虚函数,所有派

12、生类的析构函数都是虚函数 如果要操作具有继承关系的类的动态对象,最好使用虚析构函数,例子3:虚析构函数的例子,/文件employee.h,定义基类Employee #include #if !defined _EMPLOYEE_H_ #define _EMPLOYEE_H_ class Employee public: Employee() cout“Employee begin!“endl; virtual Employee() cout“Employee end!“endl; ; #endif,例子3:虚析构函数的例子,/文件programmer.h,定义派生类Programmer #in

13、clude #include #include “employee.h“ class Programmer: public Employee public: Programmer(char *str) cout“Programmer begin!“endl; name = new charstrlen(str)+1; strcpy(name, str); Programmer() delete name; cout“Programmer end!“endl; private: char *name; ;,例子3:虚析构函数的例子,/文件accountant.h,定义派生类Accountant

14、#include #include “employee.h“ class Accountant: public Employee public: Accountant(int n) cout“Accountant begin!“endl; age = n; Accountant() cout“Accountant end!“endl; private: int age; ;,例子3:虚析构函数的例子,/文件ex15_4.cpp #include “accountant.h“ #include “programmer.h“ const int MAX = 100; main() int no;

15、/声明储存雇员信息的数组 Employee *ptrMAX, *tptr; int ENum = 0; char name100; int age; for (int i=0; iMAX; i+) ptri = NULL; ,例子3:虚析构函数的例子,/输入雇员信息 coutno; while (no) switch (no) case 1: /输入程序员信息 coutname; /创建程序员对象 tptr = new Programmer(name); ptrENum+ = tptr; break;,例子3:虚析构函数的例子,case 2: /输入会计信息 coutage; /创建会计对象 tptr = new Accountant(age); ptrENum+ = tptr; break; default: break; coutno; ,例子3:虚析构函数的例子,/撤销所有雇员对象 for (i=0; iENum; i+) delete ptri; return 0; ,学习目的检测,理解静态绑定和动态绑定的概念 了解多态性的意义和作用 掌握定义虚函数和抽象基类的方法 掌握实现多态性的方法以及使用多态性的时机 了解虚析构函数的作用 掌握如何使用多态性进行软件的渐增式开发,作业,15.1 15.4 15.5,

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

当前位置:首页 > 中学教育 > 教学课件 > 高中课件

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