計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)_第1頁
計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)_第2頁
計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)_第3頁
計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)_第4頁
計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)_第5頁
已閱讀5頁,還剩47頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

計(jì)算機(jī)程序設(shè)計(jì)第12章多態(tài)性西安交通大學(xué)計(jì)算機(jī)教學(xué)實(shí)驗(yàn)中心計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第1頁。2多態(tài)性概述派生類對象替換基類對象虛函數(shù)抽象類運(yùn)算符重載本章內(nèi)容

計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第2頁。3一.多態(tài)性概述在面向?qū)ο笙到y(tǒng)中,多態(tài)性是指不同對象接收到相同的消息時(shí)會產(chǎn)生不同的行為。在C++程序中,“同名函數(shù)”即為多態(tài)性的表現(xiàn)形式。C++語言處理“多態(tài)性”的方法包括:

靜態(tài)聯(lián)編(綁定)技術(shù)動態(tài)聯(lián)編(綁定)技術(shù)

聯(lián)編(綁定)

-即函數(shù)調(diào)用與實(shí)現(xiàn)函數(shù)功能代碼的關(guān)聯(lián)。計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第3頁。4多態(tài)性的兩種處理技術(shù)靜態(tài)聯(lián)編技術(shù)-編譯時(shí)多態(tài)性

在編譯時(shí)確定調(diào)用哪一個同名函數(shù)。通過函數(shù)重載和運(yùn)算符重載實(shí)現(xiàn)。動態(tài)聯(lián)編技術(shù)-運(yùn)行時(shí)多態(tài)性

在運(yùn)行時(shí)確定調(diào)用哪一個同名函數(shù)。通過繼承和虛函數(shù)實(shí)現(xiàn)。計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第4頁。5多態(tài)性現(xiàn)象1

函數(shù)重載例:“兔子-逃生”,偽代碼描述如下:classrabbit{public:voidflee(EAGLEa){cout<<“兔子蹬鷹”;}voidflee(WOLFa){cout<<“動如脫兔”;}};

intmain(){rabbitx;EAGLEa;WOLFb;

x.flee(a);x.flee(b);}計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第5頁。6多態(tài)性現(xiàn)象2:派生類中覆蓋基類的成員函數(shù)//寵物的叫聲#include<iostream>usingnamespacestd;classPET{public:voidspeak(){cout<<"zzz"<<endl;};};classCAT:publicPET{public:voidspeak(){cout<<"miao!miao!"<<endl;}};classDOG:publicPET{public:voidspeak(){cout<<"wang!wang!"<<endl;}};計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第6頁。7voidmain(){ PET*p;//p為寵物類指針

CAT cat1; //定義貓類對象

DOG dog1; //定義狗類對象

cat1.speak();//??? dog1.speak();//??? //根據(jù)用戶輸入將貓或狗對象地址賦給p指針,

//例如用戶輸入1,則執(zhí)行p=&cat1; //用戶輸入2,則執(zhí)行p=&dog1;

p=&cat1; p->speak();??

p=&dog1; p->speak(); ??}計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第7頁。8重載:成員函數(shù)的參數(shù)有區(qū)別,即個數(shù)或類型不同。覆蓋:成員函數(shù)參數(shù)完全相同,這時(shí)派生類將覆蓋基類的同名成員函數(shù)。那么:派生類對象.成員函數(shù)()

-一定訪問派生類中覆蓋后的同名函數(shù)。派生類對象.基類名::成員函數(shù)()

-可以訪問基類中的同名函數(shù)。派生類對基類成員函數(shù)的重載與覆蓋計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第8頁。9派生類對象替換基類對象的原則

C++規(guī)定,凡是基類對象出現(xiàn)的場合都可以用其公有派生類對象進(jìn)行替換,這時(shí)派生類對象起到基類對象的作用。派生類對象替換基類對象常見的形式派生類對象給基類對象賦值pet1=cat1;派生類對象可以初始化基類對象的引用PETpet2(cat1);派生類對象的地址傳遞給基類的指針變量p=&dog1;不論哪一種形式,派生類對象替代基類對象后,只能當(dāng)做基類對象來使用。不論派生類是否存在同名覆蓋成員,這樣的基類對象所訪問的成員都只能來自基類.二.派生類對象替換基類對象計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第9頁。10三.虛函數(shù)在程序運(yùn)行時(shí),如何通過基類指針訪問當(dāng)前指向的派生類對象中覆蓋的成員函數(shù)?請使用C++中的“虛函數(shù)”技術(shù)。只需將基類中的同名成員函數(shù)定義為虛函數(shù)-加上virtual。例如將寵物類Pet中Speak()標(biāo)記為虛函數(shù):

classPet //基類{public:

virtualvoidSpeak(){cout<<"Howdoesapetspeak?"<<endl;}};計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第10頁。11虛函數(shù)的定義格式virtual

返回值類型

函數(shù)名(參數(shù)表){

函數(shù)體}虛函數(shù)的作用與用途:虛函數(shù)實(shí)現(xiàn)“一個接口,多種方法”的理念,即基類內(nèi)部的虛函數(shù)定義該函數(shù)的接口形式,而在派生類中對虛函數(shù)重新定義,創(chuàng)建一個具體的方法。使用虛函數(shù)技術(shù),可實(shí)現(xiàn)運(yùn)行時(shí)多態(tài)性,即通過基類指針指向公有派生類對象,可以訪問派生類中同名覆蓋的成員函數(shù)。計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第11頁。12虛函數(shù)的使用限制

虛函數(shù)重定義時(shí),必須保證函數(shù)名、返回值類型、參數(shù)個數(shù)、參數(shù)類型等應(yīng)于基類函數(shù)一致。?通過指針或引用調(diào)用虛函數(shù),才能保證運(yùn)行時(shí)多態(tài)性的成立。PET*p=cat1;PET&a=dog1;派生類中重定義的基類虛函數(shù)仍為虛函數(shù),同時(shí)可以省略virtual關(guān)鍵字。不能定義虛構(gòu)造函數(shù),可以定義虛析構(gòu)函數(shù)計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第12頁。13四.抽象類

抽象類:

至少包含一個純虛函數(shù)的類。純虛函數(shù)的聲明格式:virtual

返回類型函數(shù)名(參數(shù)表)=0;注意:

純虛函數(shù)在基類中只作聲明,具體實(shí)現(xiàn)過程在派生類中完成。計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第13頁。14抽象類使用的幾點(diǎn)要求:

抽象類不能實(shí)例化,即不能創(chuàng)建抽象類的對象抽象類只作為基類被繼承能夠定義指向抽象類的指針或引用計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第14頁。15例12-3抽象寵物類的實(shí)現(xiàn)classPet //基類{ char Name[20]; int Age; char Color[12];public: char Type[10]; Pet(char*,int,char*); char*GetName() {returnName;} int GetAge() {returnAge;} char*GetColor() {returnColor;}

virtualvoidSpeak()=0;

virtualvoidGetInfo(){}};計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第15頁。16Pet::Pet(char*name,intage,char*color)//基類構(gòu)造函數(shù){ strcpy(Name,name); Age=age; strcpy(Color,color); strcpy(Type,"pet");}classCat:publicPet //派生類1 {public: Cat(char*name,intage,char*color):Pet(name,age,color){} voidSpeak(){cout<<"Soundofspeak:miao!miao!"<<endl<<endl;} voidGetInfo();};voidCat::GetInfo(){ cout<<"Thecat'sname:"<<GetName()<<endl; cout<<"Thecat'sage:"<<GetAge()<<endl; cout<<"Thecat'scolor:"<<GetColor()<<endl;}計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第16頁。17另一個派生類DOGclassDog:publicPet //派生類{public: Dog(char*name,intage,char*color):Pet(name,age,color){} voidSpeak(){cout<<"Soundofspeak:wang!wang!"<<endl<<endl;} voidGetInfo();};voidDog::GetInfo(){ cout<<"Thedog'sname:"<<GetName()<<endl; cout<<"Thedog'sage:"<<GetAge()<<endl; cout<<"Thedog'scolor:"<<GetColor()<<endl;}計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第17頁。18主函數(shù)intmain(){ Pet *p1; //基類對象指針p1 p1=newCat("MiKey",1,"Blue");//動態(tài)生成Cat類對象

p1->GetInfo(); p1->Speak(); deletep1;//??? p1=newDog("BenBen",2,"Black");//動態(tài)生成Dog類對象

p1->GetInfo(); p1->Speak(); deletep1; return0;}計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第18頁。19例12-6抽象形狀類的實(shí)現(xiàn)從Point、Circle類中抽象出基類Shape。

classShape{

public:

//純虛函數(shù),在派生類中重載

virtualdoubleArea()=0;//幾何圖形面積

virtualvoidPrintShapeName()const=0;

//輸出名稱virtualvoidPrint()const=0;

};抽象類計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第19頁。20classPoint:publicShape{

intx,y;//點(diǎn)的x和y坐標(biāo)

public:

Point(int=0,int=0);

//構(gòu)造函數(shù)

voidSetPoint(int,int);//設(shè)置坐標(biāo)intGetX(){returnx;}//取x坐標(biāo)intGetY(){returny;}//取y坐標(biāo) };

Point類virtualdoubleArea(){return0.0;}

virtualvoidPrintShapeName()const{cout<<"Point:";}

virtualvoidPrint()const; //輸出點(diǎn)的坐標(biāo)虛函數(shù)的實(shí)現(xiàn)計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第20頁。21Point::Point(inta,intb){SetPoint(a,b);}voidPoint::SetPoint(inta,intb){x=a;y=b;}voidPoint::Print()const{cout<<'['<<x<<","<<y<<']';}

Point類成員函數(shù)定義計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第21頁。22classCircle:publicPoint{

doubleradius;public: Circle(intx=0,inty=0,doubler=0.0);voidSetRadius(double);

};Circle類virtualdoubleArea();//計(jì)算面積

virtualvoidPrint()const; //輸出圓心坐標(biāo)和半徑

virtualvoidPrintShapeName()const{cout<<"Circle:";}虛函數(shù)的實(shí)現(xiàn)計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第22頁。23Circle::Circle(inta,intb,doubler):Point(a,b){SetRadius(r);}voidCircle::SetRadius(doubler){radius=r;}

doubleCircle::Area(){return3.14159*radius*radius;}voidCircle::Print()const{ cout<<"Center="; Point::Print(); cout<<";Radius="<<radius<<endl;}

類外定義的虛函數(shù)類外定義的虛函數(shù)計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第23頁。24intmain(){ Pointpoint(30,50); Circlecircle(120,80,10.0);

point.PrintShapeName(); point.Print(); cout<<endl; circle.PrintShapeName(); circle.Print();

Shape*arrayOfShapes[2];//指向抽象類的指針

arrayOfShapes[0]=&point; arrayOfShapes[1]=&circle;

arrayOfShapes[0]->PrintShapeName();arrayOfShapes[1]->PrintShapeName();return0;}測試函數(shù)計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第24頁。25五.運(yùn)算符重載

重載運(yùn)算符主要用于類對象的操作。

例如:定義復(fù)數(shù)類

復(fù)數(shù)類對象的加法,c=a+b;

???運(yùn)算符重載函數(shù)的定義格式:<類型><類名>::operator<運(yùn)算符>(<參數(shù)表>){…}計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第25頁。26Complex類計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第26頁。27例12-4復(fù)數(shù)加法運(yùn)算intmain(){ Complexc1(3,4),c2(5,6),c3;……

c3=c1+c2;

cout<<"C3="<<c3.Real()<<"+i"<<c3.Imag()<<endl;

c3=c3+6.5;

cout<<"C3+6.5="<<c3.Real()<<"+i"<<c3.Imag()<<endl;return0;}計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第27頁。28計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第28頁。29例12-5classPet //基類{public: virtualvoidSpeak()=0;//??? voidShowMe();};voidPet::ShowMe(){ cout<<"我的聲音:"; Speak();}classCat:publicPet//派生類 {public: virtualvoidSpeak() {cout<<"miao!miao!"<<endl;}};計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第29頁。30本章實(shí)驗(yàn)和作業(yè)習(xí)題1虛函數(shù)的聲明和使用(BASE)120021習(xí)題2抽象類shape的應(yīng)用120024補(bǔ)充重載加法(+)運(yùn)算實(shí)現(xiàn)矩陣對象的加法120025本章要點(diǎn):重載、虛函數(shù)、純虛函數(shù)(抽象類)、運(yùn)算符的重載、基類指針訪問派生類對象。計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第30頁。31第12章實(shí)驗(yàn)與作業(yè)(P289)實(shí)驗(yàn):實(shí)驗(yàn)1(P289)實(shí)驗(yàn)2(補(bǔ)充題):參照例12-4重載對復(fù)數(shù)進(jìn)行加法、減法、乘法的運(yùn)算,并在類中增加輸出復(fù)數(shù)的成員函數(shù)PrintComplex()。作業(yè):第2題(P289)要求:正方形從Reacangle類派生

計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第31頁。329.7接口與實(shí)現(xiàn)方法的分離類的聲明在.h中類的成員函數(shù)的定義在.cpp中,與.h同名,包含.h例類Point聲明:.h#ifndefPOINT_H#definePOINT_H…#endif定義:.cpp#include“Point.h”…使用(main函數(shù))#include“Point.h”…計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第32頁。33Circle.h#ifndefCIRCLE_H#defineCIRCLE_H//#include<iostream>//usingnamespacestd;classCircle{intx,y;intradius;public: voidset(int,int,int); doublearea(); doubleperimeter();};#endif計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第33頁。34Circle.cpp#include<iostream>#include"Circle.h"usingnamespacestd;voidCircle::set(intx,inty,intr){this->x=x;this->y=y;radius=r;}doubleCircle::area(){return3.14159*radius*radius;}doubleCircle::perimeter(){return2*3.1415926*radius;}計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第34頁。35main.cpp#include<iostream>#include"Circle.h"usingnamespacestd;intmain(){ Circlec1; c1.set(1,1,1); cout<<c1.area(); cout<<endl; cout<<c1.perimeter(); cout<<endl; return0;}計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第35頁。36程序設(shè)計(jì)舉例:點(diǎn)類和圓類

在二維平面空間上,使用x,y坐標(biāo)可以確定一個點(diǎn);確定了圓心坐標(biāo)和半徑后可以確定一個圓。聲明一個點(diǎn)類,并使用這個點(diǎn)類的對象為數(shù)據(jù)成員聲明圓類。注:該例使用了類的組合、接口與實(shí)現(xiàn)方法的分離概念。通常,將類的聲明放在一個頭文件中,形成類的public接口;類成員函數(shù)的定義放在另一個源文件中,形成類的實(shí)現(xiàn)方法。計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第36頁。37問題分析點(diǎn)、圓,設(shè)置圓心、半徑,取圓心、半徑計(jì)算面積顯示圓心、半徑e計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第37頁。38//Point.h文件存放Point類的聲明#ifndefPOINT_H#definePOINT_HclassPoint//聲明Point類{ intx,y; //點(diǎn)的x和y坐標(biāo)public: voidSetPoint(int,int); //設(shè)置坐標(biāo)

intGetX(){returnx;} //取x坐標(biāo)

intGetY(){returny;} //取y坐標(biāo)

voidPrint(); //輸出點(diǎn)的坐標(biāo)};#endif計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第38頁。39//Point.cpp文件Point類的成員函數(shù)定義#include<iostream>usingnamespacestd;#include"point.h"voidPoint::SetPoint(inta,intb)//Point類成員函數(shù)的實(shí)現(xiàn){ x=a;

y=b;}voidPoint::Print(){ cout<<'['<<x<<","<<y<<']';}計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第39頁。40//Circle.h文件Circle類的聲明#ifndef

CIRCLE_H#defineCIRCLE_H#include"point.h"classCircle//聲明Circle類{private: PointCenter;//對象成員doubleRadius;計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第40頁。41public: voidSetRadius(double); //設(shè)置半徑

voidSetCenter(Point); //設(shè)置圓心坐標(biāo)

doubleGetRadius(); //取半徑

PointGetCenter(); //取圓心

doubleArea(); //計(jì)算面積

voidPrint(); //輸出圓心坐標(biāo)和半徑};#endif計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第41頁。42//Circle.cpp文件Circle類的成員函數(shù)定義#include<iostream>usingnamespacestd;#include"circle.h"voidCircle::SetRadius(doubler)//Circle類成員函數(shù)的實(shí)現(xiàn){ Radius=(r>=0?r:0);}voidCircle::SetCenter(Pointp){ Center=p;}PointCircle::GetCenter(){ returnCenter;}計(jì)算機(jī)程序設(shè)計(jì)-1多態(tài)性(趙老師)全文共52頁,當(dāng)前為第42頁。43doubleCircle::GetRadius(){ returnRadius;}doubleCircle::Area(){ return3.14159*Radius*Radi

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論