类的多态性精选文档.ppt

上传人:石*** 文档编号:45050202 上传时间:2022-09-23 格式:PPT 页数:24 大小:1.44MB
返回 下载 相关 举报
类的多态性精选文档.ppt_第1页
第1页 / 共24页
类的多态性精选文档.ppt_第2页
第2页 / 共24页
点击查看更多>>
资源描述

《类的多态性精选文档.ppt》由会员分享,可在线阅读,更多相关《类的多态性精选文档.ppt(24页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、类的多态性本讲稿第一页,共二十四页第4章 类的多态性本讲稿第二页,共二十四页一、虚函数一、虚函数1、概述、概述通俗地讲,多态是指具有相似功能的不同函数使用同一个名称来表示,通俗地讲,多态是指具有相似功能的不同函数使用同一个名称来表示,从而可以使用相同的调用方式调用具有不同功能的同名函数。从而可以使用相同的调用方式调用具有不同功能的同名函数。抽象地讲,多态是指同样的消息被不同类型的对象接收时导致完全不同的行为。抽象地讲,多态是指同样的消息被不同类型的对象接收时导致完全不同的行为。分类:分类:(1)重载多态:普通函数、类的成员函数的重载重载多态:普通函数、类的成员函数的重载(2)包含多态:基类和派

2、生类中同名成员函数问题,虚函数包含多态:基类和派生类中同名成员函数问题,虚函数(3)参数多态:函数和类的模板,通过不同实际参数的类型实例化,得到参数多态:函数和类的模板,通过不同实际参数的类型实例化,得到不同数据类型的相同操作。不同数据类型的相同操作。本讲稿第三页,共二十四页成员函数重载:成员函数重载:在子类中可以重新定义成员函数。如果增加一个与基类成员函在子类中可以重新定义成员函数。如果增加一个与基类成员函数同名的成员函数,但函数的形式参数个数、类型、次序不同,则编数同名的成员函数,但函数的形式参数个数、类型、次序不同,则编译程序可以完全识别确定。译程序可以完全识别确定。虚函数:虚函数:如子

3、类中定义的成员函数的原型与父类中的函数完全如子类中定义的成员函数的原型与父类中的函数完全相同,采用同名覆盖或者虚函数来解决,用虚函数时系统相同,采用同名覆盖或者虚函数来解决,用虚函数时系统编译不能完全确定。编译不能完全确定。本讲稿第四页,共二十四页 联编:联编:指一个计算机程序自身彼此关联的过程。可以理解成比编指一个计算机程序自身彼此关联的过程。可以理解成比编译中连接更广泛的一种连接形式。译中连接更广泛的一种连接形式。静态联编(先期联编):静态联编(先期联编):工作出现在编译阶段,在程序开始运行之前完成。即:在编译工作出现在编译阶段,在程序开始运行之前完成。即:在编译时就解决了程序中的操作调用

4、与执行该操作代码间的关系。时就解决了程序中的操作调用与执行该操作代码间的关系。动态联编(迟后联编):动态联编(迟后联编):在编译阶段不能确定将要调用的函数,只有在程序执行时在编译阶段不能确定将要调用的函数,只有在程序执行时才能确定将要调用的函数。即,联编工作在程序运行时进行。才能确定将要调用的函数。即,联编工作在程序运行时进行。本讲稿第五页,共二十四页class stu public:float cal();class graduatestu:public stupublic:float cal();例、基类例、基类/派生类中有相同的成员函数派生类中有相同的成员函数void main()stu

5、 s;graduatestu gs;s.cal();gs.cal();注:注:编译时可确定编译时可确定-静态联编静态联编本讲稿第六页,共二十四页class stu public:float cal();class graduatestu:public stupublic:float cal();void f(stu&x)x.cal();void main()stu s;graduatestu gs;f(s);f(gs);思考:思考:能不能使函数能不能使函数f根据传进来的对象的类型来决定到底是调用基类的成根据传进来的对象的类型来决定到底是调用基类的成员函数还是派生类的成员函数员函数还是派生类的成

6、员函数本讲稿第七页,共二十四页2、虚函数、虚函数在一个类中用保留字在一个类中用保留字virtual定义的成员函数,称为虚函数。定义的成员函数,称为虚函数。class basepublic:virtual void f()coutIn base.n;class subcla:public basepublic:virtual void f()coutIn suncla.n;class subclb:public basepublic:virtual void f()coutIn sunclb.n;void test(base&b)b.f();/动态决定哪一个成员函数动态决定哪一个成员函数void

7、 main()base bc;subcla sc;subclb sb;test(bc);test(sc);test(sb);本讲稿第八页,共二十四页3,虚函数的使用,虚函数的使用class memberpublic:virtual void answer()coutI am a member.n;class teacher:public memberpublic:virtual void answer()coutI am a teacher.n;class student:public memberpublic:virtual void answer()coutanswer();who=&te

8、;who-answer();who=&st;who-answer();相同的形式产生不同的动作相同的形式产生不同的动作本讲稿第九页,共二十四页运行结果:运行结果:I am a member.I am a teacher.I am a student.练习练习4.1 已知有图形圆和矩形已知有图形圆和矩形,圆有位置信息圆心点、填充颜色、半圆有位置信息圆心点、填充颜色、半径等属性,有计算面积和周长的方法;矩形有位置信息左上角的点、径等属性,有计算面积和周长的方法;矩形有位置信息左上角的点、填充颜色、长和宽等属性,有计算面积和周长的方法。要求创建一填充颜色、长和宽等属性,有计算面积和周长的方法。要求创

9、建一个图形的基类并采用虚函数的方式来实现求面积、周长以及显示图个图形的基类并采用虚函数的方式来实现求面积、周长以及显示图形具体信息的功能。形具体信息的功能。本讲稿第十页,共二十四页4、注意事项、注意事项(1)虚函数是成员函数,也只有成员函数才能说明成虚函数虚函数是成员函数,也只有成员函数才能说明成虚函数(2)内联函数不能是虚函数,因为内联函数是不能在运行中动态内联函数不能是虚函数,因为内联函数是不能在运行中动态确定其位置确定其位置(3)构造函数不能是虚函数,但可以调用虚函数构造函数不能是虚函数,但可以调用虚函数(4)析构函数可以是虚函数:析构函数可以是虚函数:声明语法:声明语法:virtual

10、 类名类名()例如:例如:class Bpublic:virtual B();一旦基类的析构函数被声明为虚函数,所有派生类的析构函数自一旦基类的析构函数被声明为虚函数,所有派生类的析构函数自动变成虚函数动变成虚函数本讲稿第十一页,共二十四页(5)虚函数与成员函数的重载不同;虚函数与成员函数的重载不同;虚函数:要求函数原型相同;否则,即使注明虚函数:要求函数原型相同;否则,即使注明virtual 也不能动态联编。也不能动态联编。函数重载:函数名相同,其他不同;函数重载:函数名相同,其他不同;(6)基类的虚函数在派生类中仍然是虚函数;在派生类中基类的虚函数在派生类中仍然是虚函数;在派生类中重定义继

11、承成员虚函数,即使不用重定义继承成员虚函数,即使不用virtual,也是虚函数。也是虚函数。(7)动态联编只能用指针、引用实现。否则,变成静态联动态联编只能用指针、引用实现。否则,变成静态联编。编。例,例,void test(base&b)b.f();不能写:不能写:void test(base b)b.f();本讲稿第十二页,共二十四页5、虚函数与构造、虚函数与构造/析构函数析构函数构造函数中调用虚函数时,采用静态联编构造函数中调用虚函数时,采用静态联编。即构造函数。即构造函数调用的虚函数是自己类中实现的虚函数。如自己类中没有实现这调用的虚函数是自己类中实现的虚函数。如自己类中没有实现这个虚

12、函数,则调用基类中的虚函数,而不是任何派生类中的虚函个虚函数,则调用基类中的虚函数,而不是任何派生类中的虚函数。数。析构函数中调用虚函数的规则一样。析构函数中调用虚函数的规则一样。本讲稿第十三页,共二十四页例,构造函数中用虚函数例,构造函数中用虚函数class Apublic:A()virtual void f()coutA:f()called.n;class B:public Apublic:B()f();void g()f();/可以显式调用,如可以显式调用,如 B:f()virtual void f()coutB:f()called.n;class C:public Bpublic:C(

13、)virtual void f()coutC:f()called.n;void main()C c;c.g();B:f()called.C:f()called.本讲稿第十四页,共二十四页二、纯虚函数和抽象类二、纯虚函数和抽象类 纯虚函数纯虚函数是一种特殊的虚函数,它的一般格式:是一种特殊的虚函数,它的一般格式:class virtual ()=0;在基类中声明但没有定义的虚函数。任何它的派生类都在基类中声明但没有定义的虚函数。任何它的派生类都必须重新定义该函数。必须重新定义该函数。本讲稿第十五页,共二十四页抽象类:抽象类:(1)一个类中至少有一个纯虚函数,则称为一个类中至少有一个纯虚函数,则称

14、为“抽象类抽象类”。(2)一个特殊的类,为了抽象和设计的目的而建立的,它一个特殊的类,为了抽象和设计的目的而建立的,它处于继承层次结构的较高层。作为基类使用。处于继承层次结构的较高层。作为基类使用。(3)抽象类不能定义对象。抽象类不能定义对象。(4)抽象类的主要作用是将有关的特性组织在一个继承层次结构抽象类的主要作用是将有关的特性组织在一个继承层次结构中,由它来提供一个公共的根,相关的子类从这个根派生出来。中,由它来提供一个公共的根,相关的子类从这个根派生出来。本讲稿第十六页,共二十四页例例 在在基基类类Shapes中中,将将成成员员display()声声明明为为纯纯虚虚函函数数,这这样样,基

15、基类类Shapes就就是是一一个个抽抽象象类类,这这时时我我们们无无法法声声明明Shapes类类的的对对象象,但但是是可可以以声声明明Shapes类类的的指指针针和和引引用用。Shapes类类经经过过公公有有派派生生产产生生了了Rectangle类类和和Circle类类。使使用用抽抽象象类类Shapes类类型型的的指指针针,当当它它指指向向某某个个派派生生类类的的对对象象时时,就可以通过它访问该对象的虚成员函数。就可以通过它访问该对象的虚成员函数。#include const double PI=3.14159;class Shapes/抽象基类抽象基类Shapes声明声明protected:

16、int x,y;public:void setvalue(int xx,int yy=0)x=xx;y=yy;virtual void display()=0;/纯虚函数成员纯虚函数成员;本讲稿第十七页,共二十四页class Rectangle:public Shapes/派生类派生类Rectangle声明声明public:/虚成员函数虚成员函数void display()coutThe area of rectangle is:x*yendl;class Circle:public Shapes/派生类派生类Circle声明声明 public:/虚成虚成员员函数函数void display(

17、)coutThe area of circle is:PI*x*xdisplay();void funRef(Shapes&refs)refs.display();本讲稿第十八页,共二十四页void main()Rectangle rect;Circle cir;rect.setvalue(20,20);cir.setvalue(10);func(&rect);funRef(cir);程序运行结果为:程序运行结果为:The area of rectangle is:400The area of circle is:314.159本讲稿第十九页,共二十四页使用抽象类时需注意以下几点:使用抽象类时

18、需注意以下几点:(1)抽象类只能用作其他类的基类,不能建立抽象类对象。抽象类只能用作其他类的基类,不能建立抽象类对象。(2)抽抽象象类类不不能能用用作作参参数数类类型型(指指针针和和引引用用是是可可以以的的)、函函数数返返回回值值或或显显式式转换的类型。转换的类型。(3)可以声明一个抽象类的指针和引用。可以声明一个抽象类的指针和引用。练习练习4.2:已知有图形三角形和正方形已知有图形三角形和正方形,三角形有三个顶点的位置、填充颜色三角形有三个顶点的位置、填充颜色等属性,有计算面积和周长的方法;正方形有中心点的位置、填充颜色、等属性,有计算面积和周长的方法;正方形有中心点的位置、填充颜色、边长等

19、属性,有计算面积和周长的方法。要求创建一个图形的抽象类并且边长等属性,有计算面积和周长的方法。要求创建一个图形的抽象类并且其中只包含纯虚函数的方式来实现求面积、周长以及显示图形具体信息的其中只包含纯虚函数的方式来实现求面积、周长以及显示图形具体信息的功能。功能。本讲稿第二十页,共二十四页多态性:多态性:建立在虚函数的概念和方法基础上。建立在虚函数的概念和方法基础上。表示:表示:发出同样的消息被不同类型的对象接受时导致完全不同的行发出同样的消息被不同类型的对象接受时导致完全不同的行为为。即同样的一个类的成员函数的调用,实现的不同性由接受对象自己确。即同样的一个类的成员函数的调用,实现的不同性由接

20、受对象自己确定。对象根据所接受到的消息而作出相应的动作。定。对象根据所接受到的消息而作出相应的动作。封装性、继承性、多态性构成了面向对象的程序设计的三大特征。封装性、继承性、多态性构成了面向对象的程序设计的三大特征。封装性是基础;继承性是关键;多态性是补充,封装性是基础;继承性是关键;多态性是补充,而多态又必须存在而多态又必须存在于继承的环境中。于继承的环境中。本讲稿第二十一页,共二十四页应用举例应用举例定义一个链表类定义一个链表类CList实现对矩形(长,宽,实现对矩形(长,宽,左上角的位置)和圆(圆心、半径)数据进行插左上角的位置)和圆(圆心、半径)数据进行插入和显示周长、面积的操作。入和

21、显示周长、面积的操作。本讲稿第二十二页,共二十四页#include Shape.htypedef struct NodeCShape*pShape;Node*pNext;TNode;class TList public:TList()pHead=NULL;Node*GetHead()return pHead;virtual TList()TNode*p=pHead,*q;while(p)delete p-pShape;q=p;p=p-pNext;delete q;本讲稿第二十三页,共二十四页void InsertShape(CShape*pShape)TNode*p=pHead,*s=new

22、TNode;s-pNext=NULL;s-pShape=pShape;if(pHead=NULL)pHead=s;return;while(p-pNext)p=p-pNext;p-pNext=s;CString PrintContent()CString strCont=链表内容链表内容:;TNode*p=pHead;while(p)CString strFormat=;strFormat.Format(名称:名称:%s,面积面积:%.3f,周长周长:%.3f;t,p-pShape-GetShapeName(),p-pShape-Area(),p-pShape-Perimeter();strCont+=strFormat;p=p-pNext;return strCont;private:TNode*pHead;本讲稿第二十四页,共二十四页

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

当前位置:首页 > 教育专区 > 大学资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁