《面向對象程序設計》多態(tài).ppt

上傳人:za****8 文檔編號:15275367 上傳時間:2020-08-06 格式:PPT 頁數(shù):45 大?。?31KB
收藏 版權申訴 舉報 下載
《面向對象程序設計》多態(tài).ppt_第1頁
第1頁 / 共45頁
《面向對象程序設計》多態(tài).ppt_第2頁
第2頁 / 共45頁
《面向對象程序設計》多態(tài).ppt_第3頁
第3頁 / 共45頁

下載文檔到電腦,查找使用更方便

9.9 積分

下載資源

還剩頁未讀,繼續(xù)閱讀

資源描述:

《《面向對象程序設計》多態(tài).ppt》由會員分享,可在線閱讀,更多相關《《面向對象程序設計》多態(tài).ppt(45頁珍藏版)》請在裝配圖網(wǎng)上搜索。

1、2020/8/6,北京科技大學計算機系,1,C+大學基礎教程,第10章 多態(tài)性 北京科技大學 計算機系,2020/8/6,北京科技大學計算機系,-2-,第十一章 多態(tài)性,11.1 多態(tài)性的概念 11.2 繼承中的靜態(tài)聯(lián)編 11.3 虛函數(shù)和運行時的多態(tài) 11.4 純虛函數(shù)和抽象類,2020/8/6,北京科技大學計算機系,-3-,多態(tài)性的概念,多態(tài)性是面向對象程序設計的重要特征之一。 多態(tài)性是指發(fā)出同樣的消息被不同類型的對象接收時導致不同的行為。 擦 地板 窗戶 臉,采用不同的工具,不同的方式。在c+中可以用相同的函數(shù)名,不同的函數(shù)操作來實現(xiàn),函數(shù)重載: 函數(shù)名相同,但是函數(shù)的參數(shù)個數(shù)或者參數(shù)類

2、型不同,或者const標識,2020/8/6,北京科技大學計算機系,-4-,11.1.1面向對象程序設計中多態(tài)的表現(xiàn),總的來說,不同對象對于相同的消息有不同的響應,就是面向對象程序設計中的多態(tài)性。 具體在程序中,多態(tài)性有兩種表現(xiàn)的方式: 同一個對象調用名字相同、但是參數(shù)不同的函數(shù),表現(xiàn)出不同的行為。重載多態(tài) 在同一個類中定義的重載函數(shù)的調用。 不同的對象調用名字和參數(shù)都相同的函數(shù),表現(xiàn)出不同的行為。-運行多態(tài) 在派生類中重復定義 同名覆蓋:使用派生類的定義 作用域符的使用:使用基類的定義,2020/8/6,北京科技大學計算機系,-5-,繼承和派生中的多態(tài),class A public: voi

3、d f( ); ; class C: public A public: void f( ); void f(int x ); ;,如果聲明:C c1; 則 c1.f( ); c1.f(int x ); c1.A:f(),2020/8/6,北京科技大學計算機系,-6-,11.1.1面向對象程序設計中多態(tài)的表現(xiàn),面向對象程序設計中多態(tài)性表現(xiàn)為以下幾種形式: 重載多態(tài):通過調用相同名字的函數(shù),表現(xiàn)出不同的行為。 運行多態(tài):通過基類的指針或引用,調用不同派生類的同名函數(shù),表現(xiàn)出不同的行為。許多面向對象程序設計的書籍中所說的多態(tài)性,就是這種多態(tài)。 模板多態(tài),也稱為參數(shù)多態(tài):通過一個模板,得到不同的函數(shù)或

4、不同的類。這些函數(shù)或者類具有不同的特性和不同的行為。,2020/8/6,北京科技大學計算機系,-7-,多態(tài)性的概念,例1 int max(int a, int b)return ab?a:b; int max(int a, int b, int c) return (int t=(ab?a:b)c?t:c; float max(float a, float b) void main() int a,b,f; float c,d; max(a,b); max(c,d); ,在編譯的時候,確定調用的是哪個max, 靜態(tài)聯(lián)編;,函數(shù)重載,2020/8/6,北京科技大學計算機系,-8-,繼承和派生中的

5、多態(tài),class A public: void f( ); ; class C: public A public: void f( ); void f(int x ); ;,如果聲明:C c1; 則 c1.f( ); c1.f(int x ); c1.A:f(),靜態(tài)聯(lián)編;,2020/8/6,北京科技大學計算機系,-9-,派生類對象調用同名函數(shù),對于派生類對象調用成員函數(shù),可以有以下的結論: 派生類對象可以直接調用本類中與基類成員函數(shù)同名的函數(shù),不存在二義性; 在編譯時就能確定對象將調用哪個函數(shù),屬于靜態(tài)聯(lián)編,不屬于運行時的多態(tài)。,2020/8/6,北京科技大學計算機系,-10-,賦值兼容原則

6、,一個公有派生類的對象在使用上可以被當作基類的對象,反之則禁止。具體表現(xiàn)在: derived d;base b; 派生類的對象可以被賦值給基類對象。 b=d; 派生類的對象可以初始化基類的引用。 base ,2020/8/6,北京科技大學計算機系,-11-,賦值兼容規(guī)則舉例 - 多態(tài)是否具有動態(tài)性,#include class B0/基類B0聲明 public: void display( ) coutB0:display( )endl; /公有成員函數(shù) ;,定義了基類,2020/8/6,北京科技大學計算機系,-12-,class B1: public B0 public: void disp

7、lay( )coutdisplay( );/對象指針-成員名 ,定義了類族,定義了基類的對象指針,2020/8/6,北京科技大學計算機系,-13-,void main( )/主函數(shù) B0 b0;/聲明B0類對象 B1 b1;/聲明B1類對象 D1 d1;/聲明D1類對象 B0 *p;/聲明B0類指針 p= ,B0:display( ),B0:display( ),B0:display( ),2020/8/6,北京科技大學計算機系,-14-,概念復習,根據(jù)賦值兼容規(guī)則,下列哪一個陳述是正確的?【 】 公有派生類的對象可以賦值給基類的對象。 任何派生類的對象可以賦值給基類的對象。 基類的對象可以賦

8、值給派生類的對象。 間接基類的對象可以賦值給直接基類的對象。,2020/8/6,北京科技大學計算機系,-15-,多態(tài)的實現(xiàn):聯(lián)編,聯(lián)編(Binding綁定):確定具體的操作對象。程序自身彼此關聯(lián)的過程,確定程序中的操作調用與執(zhí)行該操作的代碼間的關系。 靜態(tài)聯(lián)編: 編譯的多態(tài) 動態(tài)聯(lián)編: 運行時的多態(tài),int a; main() int a; a = 7; ,2020/8/6,北京科技大學計算機系,-16-,靜態(tài)聯(lián)編與動態(tài)聯(lián)編,靜態(tài)聯(lián)編(靜態(tài)束定) 聯(lián)編工作出現(xiàn)在編譯階段,用對象名或者類名來限定要調用的函數(shù)。 動畫 動態(tài)聯(lián)編 聯(lián)編工作在程序運行時執(zhí)行,在程序運行時才確定將要調用的函數(shù)。,例,例,

9、2020/8/6,北京科技大學計算機系,-17-,#include class Point public: Point(double i, double j) x=i; y=j; double Area( ) return 0.0; private: double x, y; ; class Rectangle:public Point public: Rectangle(double i, double j, double k, double l); double Area( ) return w*h; private: double w,h; ;,靜態(tài)聯(lián)編例,2020/8/6,北京科技大學

10、計算機系,-18-,Rectangle:Rectangle(double i, double j, double k, double l) :Point(i,j) w=k; h=l; void fun(Point 運行結果: Area=0,X,inaceesible,Y,inaceesible,W,private,H,private,15.0,25.0,3.0,5.2,2020/8/6,北京科技大學計算機系,-19-,例11.1 定義Circle類和Rectangle類為Shape類的派生類,通過Circle類和Rectangle類的對象調用重載函數(shù)getArea()顯示對象的面積。 / 例1

11、1.1: shape.h #ifndef SHAPE_H #define SHAPE_H class Shape public: double getArea() const; void print() const; ; / Shape類定義結束,基類Shape的定義,課下讀懂!,2020/8/6,北京科技大學計算機系,-20-,#include class Point public: Point(double i, double j) x=i; y=j; virtual double Area( ) return 0.0; private:double x, y; class Rectang

12、le:public Point public: Rectangle(double i, double j, double k, double l); virtual double Area( ) return w*h; private:double w,h; void fun(Point ,動態(tài)聯(lián)編例,虛函數(shù),運行結果: Area=375,運行結果: Area=0,聲明虛函數(shù)的目的就是通知編譯器,碰到函數(shù)名時不要馬上選擇靜態(tài)聯(lián)編,也有可能時動態(tài)聯(lián)編的。,2020/8/6,北京科技大學計算機系,21,虛函數(shù)和運行時的多態(tài),2020/8/6,北京科技大學計算機系,-22-,虛函數(shù),虛函數(shù)是動態(tài)聯(lián)編

13、的基礎。 是非靜態(tài)的成員函數(shù)。 在類的聲明中,在函數(shù)原型之前寫virtual。 virtual 只用來說明類聲明中的原型,不能用在函數(shù)實現(xiàn)時。 具有繼承性,基類中聲明了虛函數(shù),派生類中無論是否說明,同原型函數(shù)都自動為虛函數(shù)。 本質:不是重載聲明而是覆蓋。 調用方式:通過基類指針或引用,執(zhí)行時會根據(jù)指針或引用指向的對象的類,決定調用哪個函數(shù)。,2020/8/6,北京科技大學計算機系,-23-,例,#include class B0/基類B0聲明 public:/外部接口 virtual void display( ) coutB0:display( )endl; /虛成員函數(shù) ;,2020/8/

14、6,北京科技大學計算機系,-24-,class B1: public B0/公有派生 public: void display( ) coutB1:display( )endl; ; class D1: public B1/公有派生 public: void display( ) coutD1:display( )endl; ;,2020/8/6,北京科技大學計算機系,-25-,void fun(B0 *ptr)/普通函數(shù) ptr-display( ); void main( )/主函數(shù) B0 b0, *p;/聲明基類對象和指針 B1 b1;/聲明派生類對象 D1 d1;/聲明派生類對象 p=

15、/調用派生類D1函數(shù)成員 ,B0:display( ),B1:display( ),D1:display( ),2020/8/6,北京科技大學計算機系,-26-,void fun(B0 ptr)/普通函數(shù) ptr.display( ); void main( )/主函數(shù) B0 b0, *p;/聲明基類對象和指針 B1 b1;/聲明派生類對象 D1 d1;/聲明派生類對象 b0=b0; fun(b0);/調用基類B0函數(shù)成員 b0=b1; fun(b0); /調用基類B0函數(shù)成員 b0=d1; fun(b0); /調用基類B0函數(shù)成員 ,B0:display( ),B0:display( ),B

16、0:display( ),2020/8/6,北京科技大學計算機系,-27-,例11.3 將例11.2進行修改,使得程序具有運行時的多態(tài)的效果。 / 例11.3: shape1.h #ifndef SHAPE_H #define SHAPE_H class Shape public: virtual double getArea() const; void print() const; ; / Shape類定義結束,基類Shape的定義,例11.3 課下讀懂!,2020/8/6,北京科技大學計算機系,-28-,10.3.1 虛函數(shù),要實現(xiàn)運行時的多態(tài),需要以下條件: 必須通過指向基類對象的指針訪

17、問和基類成員函數(shù)同名的派生類成員函數(shù); 或者用派生類對象初始化的基類對象的引用訪問和基類成員函數(shù)同名的派生類成員函數(shù); 派生類的繼承方式必須是公有繼承; 基類中的同名成員函數(shù)必須定義為虛函數(shù)。,2020/8/6,北京科技大學計算機系,-29-,例10.4 虛函數(shù)的正確使用。分析以下程序,編譯時哪個語句會出現(xiàn)錯誤?為什么?將有錯誤的語句屏蔽掉以后,程序運行結果如何?其中哪些調用是靜態(tài)聯(lián)編,哪些是動態(tài)聯(lián)編? #include class BB public: virtual void vf1()coutBB:vf1被調用n; virtual void vf2()coutBB:vf2被調用n; vo

18、id f()coutBB:f被調用n; ; class DD:public BB public: virtual void vf1()coutDD:vf1被調用n; void vf2(int i)coutiendl; void f()coutDD:fn被調用; ;,有虛函數(shù)的基類,派生類,void main() DD d; BB *bp= ,2020/8/6,北京科技大學計算機系,-30-,void main() DD d; BB *bp= ,將這個語句注釋掉后,運行結果將顯示: DD:vf1被調用 BB:vf2被調用 BB:f被調用,函數(shù)調用bp-vf2(10);是錯誤的。因為派生類的vf2

19、函數(shù)和基類的vf2函數(shù)的參數(shù)不同,派生類的vf2就不是虛函數(shù),而是重載。,其中bp-vf1()調用是動態(tài)聯(lián)編。 bp-vf2()是靜態(tài)聯(lián)編。 bp-f()也是靜態(tài)聯(lián)編。,2020/8/6,北京科技大學計算機系,-31-,10.3.2 虛函數(shù)的使用,虛函數(shù)必須正確的定義和使用。否則,即使在函數(shù)原型前加了virtual的說明,也可能得不到運行時多態(tài)的特性。 必須首先在基類中聲明虛函數(shù)。在多級繼承的情況下,也可以不在最高層的基類中聲明虛函數(shù)。例如在第二層定義的虛函數(shù),可以和第三層的虛函數(shù)形成動態(tài)聯(lián)編。但是,一般都是在最高層的基類中首先聲明虛函數(shù)。,2020/8/6,北京科技大學計算機系,-32-,1

20、1.3.2 虛函數(shù)的使用,基類和派生類的同名函數(shù),必須函數(shù)名、返回值、參數(shù)表全部相同,才能作為虛函數(shù)來使用。否則,即使函數(shù)用virtual來說明,也不具有虛函數(shù)的行為。 靜態(tài)成員函數(shù)不可以聲明為虛函數(shù)。構造函數(shù)也不可以聲明為虛函數(shù)。 析構函數(shù)可以聲明為虛函數(shù),即可以定義虛析構函數(shù)。,2020/8/6,北京科技大學計算機系,-33-,10.3.3 虛析構函數(shù),如果用動態(tài)創(chuàng)建的派生類對象的地址初始化基類的指針,創(chuàng)建的過程不會有問題:仍然是先調用基類構造函數(shù),再執(zhí)行派生類構造函數(shù)。 但是,在用delete運算符刪除這個指針的時候,由于指針是指向基類的,通過靜態(tài)聯(lián)編,只會調用基類的析構函數(shù),釋放基類成

21、員所占用的空間。而派生類成員所占用的空間將不會被釋放。,2020/8/6,北京科技大學計算機系,-34-,#include using namespace std; class Shape public: Shape()coutShape類構造函數(shù)被調用n; Shape()coutShape類析構函數(shù)被調用n; ; / Shape類定義結束 class Circle : public Shape /派生類Circle的定義 public: Circle( int xx= 0, int yy= 0, double rr= 0.0 ) x = xx; y = yy; radius =rr; cou

22、tCircle類構造函數(shù)被調用n; Circle() coutCircle類析構函數(shù)被調用n; private: int x,y; / 圓心座標 double radius; / 圓半徑 ; / 派生類Circle定義結束 void main() Shape *shape_ptr; shape_ptr = new(Circle)(3,4,5); delete shape_ptr;,例11.5 定義簡單的Shape類和Circle類,觀察基類指針的創(chuàng)建和釋放時如何調用構造函數(shù)和析構函數(shù)。,基類Shape的定義,主函數(shù),程序運行后在屏幕上顯示: Shape類構造函數(shù)被調用 Circle類構造函數(shù)被

23、調用 Shape類析構函數(shù)被調用,2020/8/6,北京科技大學計算機系,-35-,10.3.3 虛析構函數(shù),為了解決派生類對象釋放不徹底的問題,必須將基類的析構函數(shù)定義為虛析構函數(shù)。格式是在析構函數(shù)的名字前添加virtual關鍵字。函數(shù)原型如下: virtual Shape(); 此時,無論派生類析構函數(shù)是不是用virtual來說明,也都是虛析構函數(shù)。 再用delete shape_ptr來釋放基類指針時,就會通過動態(tài)聯(lián)編調用派生類的析構函數(shù)。,2020/8/6,北京科技大學計算機系,-36-,11.3.3 虛析構函數(shù),將例11.5程序中的Shape析構函數(shù)作以上修改后,運行的結果將是: S

24、hape類構造函數(shù)被調用 Circle類構造函數(shù)被調用 Circle類析構函數(shù)被調用 Shape類析構函數(shù)被調用,2020/8/6,北京科技大學計算機系,-37-,11.4 純虛函數(shù)和抽象類,2020/8/6,北京科技大學計算機系,-38-,抽象類的一般形式,帶有純虛函數(shù)的類稱為抽象類: class 類名 virtual 類型 函數(shù)名(參數(shù)表)=0; /純虛函數(shù) . ;,一個函數(shù)聲明為純虛后,純虛函數(shù)的意思是:我是一個抽象類!不要把我實例化!純虛函數(shù)用來規(guī)范派生類的行為,實際上就是所謂的“接口”。它告訴使用者,我的派生類都會有這個函數(shù)。,2020/8/6,北京科技大學計算機系,-39-,作用,

25、抽象類為抽象和設計的目的而建立,將有關的數(shù)據(jù)和行為組織在一個繼承層次結構中,保證派生類具有要求的行為。 對于暫時無法實現(xiàn)的函數(shù),可以聲明為純虛函數(shù),留給派生類去實現(xiàn)。,2020/8/6,北京科技大學計算機系,-40-,注意,抽象類只能作為基類來使用。 不能聲明抽象類的對象。 構造函數(shù)不能是虛函數(shù),析構函數(shù)可以是虛函數(shù)。 eg. class A public: virtual void fun1()=0; ; A obj;,2020/8/6,北京科技大學計算機系,-41-,例,1)了解純虛函數(shù)的定義 2)了解純虛類只能作為基類,派生其他類而用 class A public: A()fun();

26、virtual void fun() cout “A:fun”endl; ; class B : public A public: B() fun(); void fun() cout “B:fun”endl; ; B b;,1 構造函數(shù)中調用的虛函數(shù)不具有動態(tài)聯(lián)編,必然是調用的本類中的函數(shù)。 2 Virtual void fun()=0;,virtual void fun() =0;,2020/8/6,北京科技大學計算機系,-42-,class A public: void foo() bar(); private: virtual void bar() . ; class B: publi

27、c A private: virtual void bar() . ; void bar1 (A *a) a-foo();,bar函數(shù)中調用a對象的foo,foo中調用虛函數(shù)bar,調用的是哪個bar。,2020/8/6,北京科技大學計算機系,-43-,一個類的虛函數(shù)在它自己的構造函數(shù)和析構函數(shù)中被調用的時候,它們就變成普通函數(shù)了,不“虛”了。也就是說不能在構造函數(shù)和析構函數(shù)中讓自己“多態(tài)”。例如: class A public: A() foo(); / 在這里,無論如何都是A:foo()被調用! A() foo(); / 同上 virtual void foo(); ; class B:

28、public A public: virtual void foo(); ; void bar() A * a = new B; delete a; ,2020/8/6,北京科技大學計算機系,-44-,多態(tài)有什么用? 在面向對象的編程中,首先會針對數(shù)據(jù)進行抽象(確定基類)和繼承(確定派生類),構成類層次。 類層次的使用者在使用它們的時候,如果仍然在需要基類的時候寫針對基類的代碼,在需要派生類的時候寫針對派生類的代碼,就等于類層次完全暴露在使用者面前。 如果這個類層次有任何的改變(增加了新類),都需要使用者“知道”(針對新類寫代碼)。這樣就增加了類層次與其使用者之間的耦合,有人把這種情況列為程序中的“bad smell”之一。,2020/8/6,北京科技大學計算機系,-45-,總結,多態(tài)性是面向對象程序設計最重要的特點之一。本章介紹了多態(tài)性中最重要的兩個表現(xiàn):運行多態(tài)和參數(shù)多態(tài)。參數(shù)多態(tài)就是模板的使用。 運行多態(tài)的表現(xiàn)就是: 一種形態(tài)的語句:通過基類指針訪問基類和派生類的同名函數(shù); 多種條件的執(zhí)行:用不同派生類對象的地址初始化這個基類指針;,

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

相關資源

更多
正為您匹配相似的精品文檔
關于我們 - 網(wǎng)站聲明 - 網(wǎng)站地圖 - 資源地圖 - 友情鏈接 - 網(wǎng)站客服 - 聯(lián)系我們

copyright@ 2023-2025  zhuangpeitu.com 裝配圖網(wǎng)版權所有   聯(lián)系電話:18123376007

備案號:ICP2024067431-1 川公網(wǎng)安備51140202000466號


本站為文檔C2C交易模式,即用戶上傳的文檔直接被用戶下載,本站只是中間服務平臺,本站所有文檔下載所得的收益歸上傳人(含作者)所有。裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對上載內容本身不做任何修改或編輯。若文檔所含內容侵犯了您的版權或隱私,請立即通知裝配圖網(wǎng),我們立即給予刪除!