您好,欢迎访问三七文档
继承和多态-3第十五章2回顾基类和派生类对象的转换类指针的使用多重继承复合与继承的关系虚基类概念虚基类构造函数虚继承3目标静态绑定和动态绑定的概念多态性的意义和作用虚函数的定义方法抽象基类的作用和定义方法虚析构函数的作用和使用方法如何在程序中实现多态性4静态绑定与动态绑定静态绑定编译时就能确定一条函数调用语句要调用的函数在程序编译时多态性体现在函数和运算符的重载上动态绑定运行时才能确定函数调用语句调用的函数程序运行时的多态性通过继承和虚函数来体现5多态性的概念多态性是面向对象程序设计的重要特征之一多态性概念:具有继承关系的类,其对象对同一个函数调用可以作出不同的响应同一个函数调用——同一条函数调用语句不同的响应——执行不同的函数6多态性的优点多态性有助于更好地对程序进行抽象控制模块能专注于一般性问题的处理具体的操作交给具体的对象去做多态性有助于提高程序的可扩展性可以把控制模块与被操作的对象分开可以添加已定义类的新对象,并能管理该对象可以添加新类(已有类的派生类)的新对象,并能管理该对象7虚函数虚函数的概念:在基类中冠以关键字virtual的成员函数虚函数的定义:virtual函数类型函数名称(参数列表);如果一个函数在基类中被声明为虚函数,则他在所有派生类中都是虚函数(包括重定义函数)只有通过基类指针或引用调用虚函数才能引发动态绑定8虚函数的使用2-1//文件base.h定义基类#if!definedBASE_H#defineBASE_HclassBase{public:virtualvoidshow();};#endif//文件base.cpp基类的实现#include“base.h”#includeiostream.hvoidBase::show(){coutIamBase'sobject!\n;}//文件derived.h定义派生类Derived#if!definedDERIVED_H#defineDERIVED_H#includebase.hclassDerived:publicBase{public:voidshow();};#endif#include“derived.h”#includeiostream.hvoidDerived::show(){coutIamDerived'sobject!\n;}9虚函数的使用2-2//main函数文件//测试多重继承的类层次#includederived.hintmain(){Base*bPtr,bObj;DeriveddObj;bPtr=&bObj;//基类指针指向基类对象bPtr-show();//用基类指针调用成员函数,动态绑定bPtr=&dObj;//基类指针指向基类对象bPtr-show();//用基类指针调用成员函数,动态绑定return0;}10虚函数的注意事项在类体系中访问一个虚函数时,应使用指向基类类型的指针或对基类类型的引用,以满足运行时多态性的要求。当然也可以像调用普通成员函数那样利用对象名来调用一个函数。在派生类中重新定义虚函数时,必须保证该函数的值和参数与基类中的说明完全一致,否则就属于重载若在派生类中没有重新定义虚函数,则该类的对象将使用其基类中的虚函数代码。虚函数必须是类的一个成员函数,不能是友元,但它可以是另一个类的友元。虚函数不得是一个静态成员。11虚函数和重载函数的区别成员函数被重载需要在相同范围(同一个类中),而虚函数要求在不同的范围(一个在派生类,一个在基类)重载函数要求函数有相同函数名称,并有不同的参数序列;而虚函数则要求函数名、返回值类型和参数序列完全相同重载函数可以是成员函数或友员函数,而虚函数只能是成员函数重载函数的调用是以所传递参数序列的差别作为调用不同函数的依据;虚函数是根据对象的不同去调用不同类的虚函数虚函数在运行时表现出多态功能,这是C++的精髓;而重载函数则在编译时表现出多态性12虚析构函数2-1动态对象的创建newClassName(…);ClassName指明了要调用的构造函数动态对象的撤销delete基类指针;如果基类指针指向的是派生类的对象呢?13虚析构函数2-2析构函数可以声明为虚函数delete基类指针;程序会根据基类指针指向的对象的类型确定要调用的析构函数基类的析构函数为虚函数,所有派生类的析构函数都是虚函数构造函数不得是虚函数如果要操作具有继承关系的类的动态对象,最好使用虚析构函数。特别是在析构函数需要完成一些有意义的操作——比如释放内存时14虚析构函数使用4-1//文件employee.h,定义基类Employee#includeiostream.h#if!definedEMPLOYEE_H#defineEMPLOYEE_HclassEmployee{public:Employee(){coutEmployeebegin!endl;}virtual~Employee(){coutEmployeeend!endl;}};#endif//文件accountant.h定义派生类Accountant#includeiostream.h#includeemployee.hclassAccountant:publicEmployee{public:Accountant(intn){coutAccountantbegin!“endl;age=n;}~Accountant(){coutAccountantend!endl;}private:intage;};15虚析构函数使用4-2//文件programmer.h//定义派生类Programmer#ifndefPROGRAMMER_H#definePROGRAMMER_H#includeemployee.hclassProgrammer:publicEmployee{public:Programmer(char*str);~Programmer();private:char*name;};#endif//文件programmer.cppinclude“programmer.h”#includeiostream.h#includestring.hProgrammer::~Programmer(){delete[]name;coutProgrammerend!“endl;}Programmer::Programmer(char*str){coutProgrammerbegin!“endl;name=newchar[strlen(str)+1];strcpy(name,str);}16虚析构函数使用4-3#includeaccountant.h#includeprogrammer.hconstintMAX=100;voidmain(){intno;//声明储存雇员信息的数组Employee*ptr[MAX],*tptr;intENum=0;charname[100];intage;for(inti=0;iMAX;i++){ptr[i]=NULL;}//输入雇员信息coutInputemployees'info:“endl;cout1---Programmer“endl2---Accountantendl0---exitendl;cinno;while(no){17虚析构函数使用4-4switch(no){case1://输入程序员信息coutPleaseinputhisorhername:;cinname;tptr=newProgrammer(name);ptr[ENum++]=tptr;break;case2://输入会计信息coutPleaseinputhisorherage:;cinage;tptr=newAccountant(age);ptr[ENum++]=tptr;break;default:break;}coutInputanotheremployee'sinfo:“endl;cout1---Programmerendl2---Accountantendl0---exit“endl;cinno;}}18纯虚函数2-1实现多态性的前提需要有共同的基类需要在基类中定义共同的接口接口要定义为虚函数如果基类的接口没办法实现怎么办?如形状类Shape解决方法不实现这些接口:纯虚函数包含纯虚函数的类:抽象基类19纯虚函数2-2在基类中不能给出有意义的虚函数定义,这时可以把它说明成纯虚函数,把它的定义留给派生类来做定义纯虚函数:class类名{virtual返回值类型函数名(参数表)=0;};纯虚函数不需要实现20抽象类2-1如果一个类中至少有一个纯虚函数,那么这个类被成为抽象类(abstractclass)抽象类存在的意义是作为其它类的基类,也叫抽象基类主要作用:取若干类的共同行为,形成更清晰的概念层次。使用抽象类符合程序设计中的单选原则(singlechoiceprinciple)。21抽象类2-2抽象类不能用于直接创建对象实例,可以声明抽象类的指针和引用可使用指向抽象类的指针支持运行时多态性派生类中必须重载基类中的纯虚函数,否则它仍将被看作一个抽象类22抽象类的使用4-1//文件shape.h//定义抽象基类Shape#if!definedSHAPE_H#defineSHAPE_H#includeiostream.hclassShape{public:virtualdoublearea()const=0;virtualvoidshow()const=0;};#endif23抽象类的使用4-2//文件circle.h,定义派生类Circle#if!definedCIRCLE_H#defineCIRCLE_H#includeshape.h#definePI3.1416classCircle:publicShape{public:Circle(double=0.0,double=0.0,double=1.0);doublearea()const;voidshow()const;private:doublex,y;doubler;};#endif//文件circle.cpp,实现类Circle#includecircle.hCircle::Circle(doublea,doubleb,doublec){x=a;y=b;r=c;}doubleCircle::area()const{returnPI*r*r;}voidCircle::show()const{coutIamaCircle:;}24抽象类的使用4-3//文件rectangle.h//定义派生类Rectangle#if!defined__RECTANGLE__H__#define__RECTANGLE__H__#includeshape.hclassRectangle:publicShape{public:Rectangle(double=1.0,double=1.0);doublearea()const;voidshow()const;private:doublelength;doublewidth;};#endif//文件rectangle.cpp,实现类Rectangle#includerectangle.hRectangle::Rectangle(doublea,doubleb){length=a;width=b;}doubleRectangle::area()const{returnlength*width;}voidRectangle::show()const{coutIamaRectangle:;}25抽象类的使用4-4#includecircle.h#inc
本文标题:15继承和多态-3
链接地址:https://www.777doc.com/doc-3200803 .html