多态性(Polymorphism)是指一个名字,多种语义;或界面相同,多种实现。重载函数是多态性的一种简单形式。虚函数允许函数调用与函数体的联系在运行时才进行,称为动态联编。第8章虚函数与多态性8.1静态联编8.2类指针的关系8.3虚函数与动态联编8.4纯虚函数与抽象类8.5虚函数和多态性的应用小结第8章虚函数与多态性联编是指一个程序模块、代码之间互相关联的过程。静态联编,是程序的匹配、连接在编译阶段实现,也称为早期匹配。重载函数使用静态联编。动态联编是指程序联编推迟到运行时进行,所以又称为晚期联编。switch语句和if语句是动态联编的例子。8.1静态联编8.1静态联编普通成员函数重载可表达为两种形式:1.在一个类说明中重载例如:Show(int,char);Show(char*,float);8.1静态联编普通成员函数重载可表达为两种形式:1.在一个类说明中重载例如:Show(int,char);与Show(char*,float);不是同一函数,编译能够区分2.基类的成员函数在派生类重载。有3种编译区分方法:(1)根据参数的特征加以区分8.1静态联编普通成员函数重载可表达为两种形式:1.在一个类说明中重载2.基类的成员函数在派生类重载。有3种编译区分方法:(1)根据参数的特征加以区分例如:A::Show();有别于B::Show();(2)使用“::”加以区分8.1静态联编普通成员函数重载可表达为两种形式:1.在一个类说明中重载2.基类的成员函数在派生类重载。有3种编译区分方法:(1)根据参数的特征加以区分(2)使用“::”加以区分例如:Aobj.Show()调用A::Show()Bobj.Show()调用B::Show()(3)根据类对象加以区分根据this指针类型区分基类指针和派生类指针与基类对象和派生类对象4种可能匹配:直接用基类指针引用基类对象;直接用派生类指针引用派生类对象;用基类指针引用一个派生类对象;用派生类指针引用一个基类对象。8.2类指针的关系8.2类指针的关系例如:A*p;//指向类型A的对象的指针AA_obj;//类型A的对象BB_obj;//类型B的对象p=&A_obj;//p指向类型A的对象p=&B_obj;//p指向类型B的对象,它是A的派生类利用p,可以通过B_obj访问所有从A类继承的元素,但不能用p访问B类自定义的元素(除非用了显式类型转换)classAclassB:publicA8.2.1基类指针引用派生类对象8.2.1基类指针引用派生类对象#includeiostream.h#includestring.hclassA_class{charname[20];public:voidput_name(char*s){strcpy(name,s);}voidshow_name(){coutname\n;}};classB_class:publicA_class{charphone_num[20];public:voidput_phone(char*num){strcpy(phone_num,num);}voidshow_phone(){coutphone_num\n;}};voidmain(){A_class*A_p;A_classA_obj;B_classB_obj;A_p=&A_obj;A_p-put_name(Wangxiaohua);A_p-show_name();A_p=&B_obj;A_p-put_name(Chenming);A_p-show_name();B_obj.put_phone(5555_12345678);((B_class*)A_p)-show_phone();}例8-1使用基类指针引用派生类对象classA_classclassB_class:publicA_class8.2.1基类指针引用派生类对象#includeiostream.h#includestring.hclassA_class{charname[20];public:voidput_name(char*s){strcpy(name,s);}voidshow_name(){coutname\n;}};classB_class:publicA_class{charphone_num[20];public:voidput_phone(char*num){strcpy(phone_num,num);}voidshow_phone(){coutphone_num\n;}};voidmain(){A_class*A_p;A_classA_obj;B_classB_obj;A_p=&A_obj;A_p-put_name(Wangxiaohua);A_p-show_name();A_p=&B_obj;A_p-put_name(Chenming);A_p-show_name();B_obj.put_phone(5555_12345678);((B_class*)A_p)-show_phone();}基类指针classA_classclassB_class:publicA_class8.2.1基类指针引用派生类对象例8-1使用基类指针引用派生类对象#includeiostream.h#includestring.hclassA_class{charname[20];public:voidput_name(char*s){strcpy(name,s);}voidshow_name(){coutname\n;}};classB_class:publicA_class{charphone_num[20];public:voidput_phone(char*num){strcpy(phone_num,num);}voidshow_phone(){coutphone_num\n;}};voidmain(){A_class*A_p;A_classA_obj;B_classB_obj;A_p=&A_obj;A_p-put_name(Wangxiaohua);A_p-show_name();A_p=&B_obj;A_p-put_name(Chenming);A_p-show_name();B_obj.put_phone(5555_12345678);((B_class*)A_p)-show_phone();}基类指针指向基类对象classA_classclassB_class:publicA_class8.2.1基类指针引用派生类对象例8-1使用基类指针引用派生类对象#includeiostream.h#includestring.hclassA_class{charname[20];public:voidput_name(char*s){strcpy(name,s);}voidshow_name(){coutname\n;}};classB_class:publicA_class{charphone_num[20];public:voidput_phone(char*num){strcpy(phone_num,num);}voidshow_phone(){coutphone_num\n;}};voidmain(){A_class*A_p;A_classA_obj;B_classB_obj;A_p=&A_obj;A_p-put_name(Wangxiaohua);A_p-show_name();A_p=&B_obj;A_p-put_name(Chenming);A_p-show_name();B_obj.put_phone(5555_12345678);((B_class*)A_p)-show_phone();}基类指针调用基类成员函数classA_classclassB_class:publicA_class8.2.1基类指针引用派生类对象例8-1使用基类指针引用派生类对象#includeiostream.h#includestring.hclassA_class{charname[20];public:voidput_name(char*s){strcpy(name,s);}voidshow_name(){coutname\n;}};classB_class:publicA_class{charphone_num[20];public:voidput_phone(char*num){strcpy(phone_num,num);}voidshow_phone(){coutphone_num\n;}};voidmain(){A_class*A_p;A_classA_obj;B_classB_obj;A_p=&A_obj;A_p-put_name(Wangxiaohua);A_p-show_name();A_p=&B_obj;A_p-put_name(Chenming);A_p-show_name();B_obj.put_phone(5555_12345678);((B_class*)A_p)-show_phone();}classA_classclassB_class:publicA_class基类指针指向派生类对象8.2.1基类指针引用派生类对象例8-1使用基类指针引用派生类对象#includeiostream.h#includestring.hclassA_class{charname[20];public:voidput_name(char*s){strcpy(name,s);}voidshow_name(){coutname\n;}};classB_class:publicA_class{charphone_num[20];public:voidput_phone(char*num){strcpy(phone_num,num);}voidshow_phone(){coutphone_num\n;}};voidmain(){A_class*A_p;A_classA_obj;B_classB_obj;A_p=&A_obj;A_p-put_name(Wangxiaohua);A_p-show_name();A_p=&B_obj;A_p-put_name(Chenming);A_p-show_name();B_obj.put_phone(5555_12345678);((B_class*)A_p)-show_phone();}classA_classclassB_class:publicA_class调用从基类继承的成员函数8.2.1基类指针引用派生类对象例8-1使用基类指针引用派生类对象#includeiostream.h#includestring.hclassA_class{charname[20];public:voidput_name(char*s){strcpy(name,s);}voidshow_name(){coutname\n;}};classB_class:publicA_class{charphone_num[20];public:voidput_phone(char*num){strcpy(phone_num,num);}voidshow_phone(){coutphone_num\n;}};voidmain(){A_class*A_p;A_classA_obj;B_classB_obj;A_p=&A_obj;A_p-put_name(Wangxiaohua);A_p-show_name();A_p=&B_obj;A_p-put_name(Chenming);A_p-show_name();B_obj.put_phone(5555_12