《面向对象编程技术第八章.ppt》由会员分享,可在线阅读,更多相关《面向对象编程技术第八章.ppt(47页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第八章第八章 多态多态1.问题的提出问题的提出2.多态多态在本章在本章的表现形式的表现形式3.总结与建议总结与建议去工作吧去工作吧去工作吧去工作吧去工作吧去工作吧去工作吧去工作吧头说:大家去工作吧头说:大家去工作吧1.多态多态定义定义:不同类型的对象接收同样的消息产生不:不同类型的对象接收同样的消息产生不同的行为同的行为2.现实现实需要需要多态;面向对象多态;面向对象需要需要多态:它以归整划一多态:它以归整划一的方式在特定时刻处理多个类型不同的对象的方式在特定时刻处理多个类型不同的对象返返 回回1.运算符重载运算符重载2.虚函数虚函数3.抽象类纯虚函数抽象类纯虚函数多态在本章主要的表现形式多态
2、在本章主要的表现形式返返 回回运运算算符符重重载载1.设计思想2.运算符重载的基本形式3.运算符重载的实例4.注意事项返返 回回运算符重载设计思想运算符重载设计思想1.扩展系统已有运算符的功能,能处理自定义数据类型2.定义与特定运算符同名的函数3.此函数与类相关联(成员或友元)4.以函数处理特定的自定义数据类型5.C系统通过函数重载的方式来定位、执行此特殊函数返返 回回运算符重载分类运算符重载分类运运算算符符重重载载按载体类的成员函数类的友元函数按对象个数重载单目运算符:前置与后置重载双目运算符返返 回回可以重载为普通函数吗?看完所有例子再回答,呵呵!重载分类之一重载分类之一1.重载为类成员函
3、数参数个数=原操作数个数 1(后置+、-除外)2.重载为友元函数参数个数=原操作数个数,且至少应该有一个自定义类型的形参要理解参数个数的原因格式重载为类成员函数格式重载为类成员函数格式:函数类型函数类型 operator 运算符(形参)运算符(形参).重载为友元函数格式重载为友元函数格式friendly 函数类型函数类型 operator 运算符(形参)运算符(形参).返返 回回Operator:重:重载关键字载关键字重载分类之二重载分类之二单目运算符1.前置单目运算符:U oprd 无形参,表达式 U oprd 相当于 oprd.operator U()2.后置单目运算符 oprd U有一个
4、 int 类型形参表达式 oprd+相当于 oprd.operator+(0)oprd 为特定的对象重载分类之二重载分类之二oprd1、oprd2 为特定类的对象双目运算符B:重载后:表达式 oprd1 B oprd2 相当于 oprd1.operator B(oprd2)返返 回回重载举例重载举例1用“+”、“-”能够实现复数的加减运算class complexpublic:complex(double r=0.0,double i=0.0)real=r;imag=i;friend complex operator+(complex c1,complex c2);/重载为友元友元函数comp
5、lex operator-(complex c1);/重载为成员成员函数void display();/显示复数的值private:/私有数据成员double real;double imag;跳跳 回回complex operator+(complex c1,complex c2)/运算符重载友元函数实现 return complex(c2.real+c1.real,c2.imag+c1.imag);complex complex:operator-(complex c1)/运算符重载成员函数实现 return complex(real-c1.real,imag-c1.imag);void
6、complex:display()cout(real,imag)endl;注意:注意:重载为类的成员函数,操作对象个数少一重载为类的成员函数,操作对象个数少一void main()/主函数 complex c1(5,4),c2(2,10),c3;/声明复数类的对象coutc1=;c1.display();coutc2=;c2.display();c3=c1-c2;/使用重载运算符完成复数减法coutc3=c1-c2=;c3.display();c3=c1+c2;/使用重载运算符完成复数加法coutc3=c1+c2=;c3.display();程序运行结果:c1=(5,4)c2=(2,10)c3
7、=c1-c2=(3,-6)c3=c1+c2=(7,14)请看一个对此例改装的例子补充例子#include iostream.hstruct complex double real;double imag;/friend complex operator+(complex c1,complex c2);/complex operator+(complex c1,complex c2);/重载为友元函数complex operator+(complex c1,complex c2)complex c3;c3.imag=c1.imag+c2.imag;c3.real=c1.real+c2.real;
8、return c3;void main()/主函数complex c1,c2,c3;/声明复数结构体变量c1.imag=1;c2.imag=2;c1.real=3;c2.real=4;c3=c1+c2;/使用重载运算符完成复数加法coutc3=c1+c2endl;coutc3.image=:c3.imagendl;coutc3.real=:c3.real=60)Second=Second-60;Minute+;if(Minute=60)Minute=Minute-60;Hour+;Hour=Hour%24;cout=60)Second=Second-60;Minute+;if(Minute=6
9、0)Minute=Minute-60;Hour+;Hour=Hour%24;coutClock+:;/其它成员函数的实现略void main()Clock myClock(23,59,59);coutFirst time output:;myClock.ShowTime();myClock+;myClock.ShowTime();+myClock;myClock.ShowTime();程序运行结果为:First time output:23:59:59Clock+:0:0:0+Clock:0:0:11.不可以重载C+中的运算符:.、.*、?:、:、sizeof 2.只能重载C+语言中已有的运算
10、符,不可臆造新的。3.不改变原运算符操作数个数、优先级和结合性。注意注意(6点点):有一定的原因4.C+系统对重载运算符的选择,遵循函数重载的原则5.经重载的运算符,其操作数中至少应该有一个是自定义类型。6.运算符重载是对已有的运算符赋予多重含义返返 回回虚函数虚函数虚函数设计思想:为了实现类族中多个对象运行时的多态 对比虚基类:为了解决继承中产生的二义性问题什么是二义性问题慢慢体会慢慢体会虚函数的定义格式定义:基类中将某一成员函数用virtural 声明派生类中用函数原型相同的函数超越、覆盖超越、覆盖(overriding)它对比重载(overloaded)class baseAvirtua
11、l void f().class deriveB:public baseAvoid f()例例1:#include class B0/基类B0声明public:/外部接口virtual void display()coutB0:display()endl;/虚成员函数;虚函数虚函数class B1:public B0/公有派生 public:void display()coutB1:display()endl;class D1:public B1/公有派生 public:void display()coutD1:display()display();void main()B0 b0,*p;/声
12、明基类对象和指针B1 b1;/声明派生类对象D1 d1;/声明派生类对象p=&b0;fun(p);/调用基类B0函数成员p=&b1;fun(p);/调用派生类B1函数成员p=&d1;fun(p);/调用派生类D1函数成员程序运行结果为:程序运行结果为:B0:display()B1:display()D1:display()跳跳 回回/抽象类定义class vehicle public:vehicle(float speed,int total)/构造函数 vehicle:speed=speed;vehicle:total=total;virtual void showmember()=0;/纯
13、虚函数的定义 protected:float speed;int total;例例2:class car public:vehicle /抽象类派生类 public:/派生类的构造函数,实现基类的构造函数 car(int aird,float speed,int total):vehicle(speed,total)car:aird=aird;virtual void showmember()/派生类函数重载 coutspeed1total2endl;protected:int aird;调用如下:int main(void)car b(250,150,4);b.showmember();re
14、turn 0;什么情况下需要使用纯虚函数?什么情况下需要使用纯虚函数?要在基类中抽象出一个方法,且该类被继承而不能被实例化时。要在基类中抽象出一个方法,且该类被继承而不能被实例化时。基类的方法必须在派生类中被实现时。基类的方法必须在派生类中被实现时。多个对象具有公共的抽象属性,但却有不同的实现要求时。多个对象具有公共的抽象属性,但却有不同的实现要求时。虚函数小结:注意注意(6点点):1.虚函数是非静态成员函数;是动态联编的基础2.虚函数具有传递继承性,基类中声明了虚函数,派生类中无论是否说明,同原型函数同原型函数都自动为虚函数3.在类的声明中,在函数原型之前写virtual,不能用在函数实现(
15、定义)时。无需为整个类的对象共享4.本质:不是重载而是覆盖。5.调用方式:通过基类指针或引用,执行时会根据指针指向的对象的类,决定调用哪个函数。6.构造函数不能是虚函数,析构函数可以是虚函数/参考书上参考书上P265 例例8.5返返 回回抽象类纯虚函数抽象类纯虚函数带有纯虚函数的类称为抽象类class 类名 virtual 类型类型 函数名函数名(参数表参数表)=0;/纯虚函数纯虚函数.纯虚函数的定义格式定义纯虚函数的目的:和虚函数类似,与Java中的接口类类似,并且对于本类不定义其函数体举例:举例:#include class B0 /抽象基类b0声明public:/外部接口virtual
16、void display()=0;/纯虚函数成员 ;对比:void f()class B1:public B0/公有派生public:void display()coutB1:display()endl;/虚成员函数;class D1:public B1/公有派生public:void display()coutD1:display()display();void main()/主函数 B0*p;/声明抽象基类指针B1 b1;/声明派生类对象D1 d1;/声明派生类对象p=&b1;fun(p);/调用派生类B1函数成员p=&d1;fun(p);/调用派生类D1函数成员程序的运行结果为:B1:d
17、isplay()D1:display()注意:注意:1.抽象类是类的抽象抽象的抽象2.对于暂时无法定义的函数,可以声明为纯虚函数,给派生类去实现。3.抽象类只能作为基类来使用、不能声明抽象类的对象。4.可以定义抽象的指针或引用来指向其派生类的对象,5.访问其派生类函数成员从而体现多态的特征返返 回回行为的抽象多态多态的含义的含义1.重载多态重载多态2.强制多态强制多态3.包含多态包含多态4.参数多态参数多态函数模板、类函数模板、类模板模板本本 章章 总总 结结专用多态通用多态将对象类型强制将对象类型强制转换适应计算的转换适应计算的需求需求通过动态联编通过动态联编实现实现多态的执行机制多态的执行机制编译多态:通过静态联编实现 如:重载多态、强制多态、参数多态运行多态:通过动态联编实现 如:包含多态(研究类族中不同类中同名函数成员的行为)注意:注意:联编是指消息与对象的方法(函数成员的入口)绑定的过程多态性是面向对象程序设计的重要特征之一。多态性是指发出同样的消息被不同类型的对象接收时导致不同的行为。明白了!明白了!建建 议议认真做试验去体会多态与运用多态认真做试验去体会多态与运用多态