2-5 多態性與虛擬函式


阿瑟 發表



在此篇教學中涵蓋了基本的 多態性 (polymorphism) 與 虛擬函式 (virtual functions).

*注意: C++所有語法大小寫有差. 如果您在執行時發現中文無法顯示請自行將程式修改成英文.

*注意: 如果您執行程式後, 程式視窗會自動關閉的話, 請至MS-DOS模式重新執行程式, 或是在void main()最底端加上system("PAUSE");來暫停程式.



什麼是多態性 (polymorphism) 呢?

多態性就是當你對一個擁有特殊性質的物件進行函式呼叫, 出來的結果可能來自兩個不同的類別.

先來看個範例:

#include <iostream.h>
#include <stdlib.h>

class rectangle
{
   public:
   virtual void output(); //虛擬函式, 等一下會介紹
   void output2(); 
};

class square : public rectangle
{
   public:
   void output(); //square中的兩個函式由於和rectangle名稱相同, 因此會取代繼承來的函式
   void output2();
};

void rectangle::output()
{
   cout << "這是一個長方形" << endl;
}

void rectangle::output2()
{
   cout << "這是一個長方形, 非正方形" << endl;
}

void square::output()
{
   cout << "這是一個正方形" << endl;
}

void square::output2()
{
   cout << "這是一個正方形, 也算是長方形" << endl;
}

void main()
{
   rectangle *one; //這是一個rectangle的指標物件
   square two; //這是一個square物件

   one = &two; //從這邊就比較奇怪一點,
               //把rectangle指標指向一個square物件的記憶體位置?

   one -> output(); //虛擬函式被square物件給取代了, 呼叫square::output(), 展現多態性
   one -> output2(); //呼叫rectangle::output2(), 非多態

   two.output(); //剩下這兩個都是呼叫square下的函式
   two.output2();

   system("PAUSE");

}



在這個範例中, one本身是一個rectangle的指標, 但是由於output()函式本身是虛擬函式 (virtual function), 因此當我們將一個sqaure的物件位置指定給一個rectangle的指標 (這個物件就擁有這兩個類別的部分特性了, 夠特殊吧), 就會被取代.

當從one指標執行output()的時候, 他會執行實際物件內容的output(), 也就是square::output(). 而 one -> output2(); (不要懷疑, 這就是指標呼叫函式的方法) 本身不是虛擬函式, 因此會執行指標型態的output2()函式, 也就是rectangle::output2(). 總之只要記得一件事, 除非是虛擬函式, 否則執行函式都會遵照指標類型.

而two應該就不用說了, 他只是一個很陽春的物件. two是sqaure類別的物件, 而square中含有與rectangle相同名稱的函式, 因此square繼承rectangle類別的時候會以自身的函式取代繼承來的函式, 因此輸出當然就是square::output()與square::output2()兩個函式了.


這樣一來大家對多態性應該有基本的認識了...
但是在哪裡可以運用的到呢?

假如說你今天設計了一個類別, 然後程式已經正常運行了. 但是過了一陣子你又寫了新的類別去繼承原有的類別 - 多態性讓你可以用一種指標或是參考資料型態來使用不同類別的物件 (但多半都是繼承同樣的父類別).


介紹了多態性以後, C++的部分小弟就先告一個段落了.
小弟原先學習C++是希望能夠進入Java與Visual C++的部分 (這兩個領域沒有C++基礎不行), 因此其他的C++函式庫小弟都比較少去碰, 如果有空的話大家不妨上微軟的MSDN (http://msdn.microsoft.com)的library看看, 裡面有不少C++的參考資料.
中文的參考資料國內各大學資訊科系學生的網站應該也有不少.

別忘了要多練習, 功力才會進步喲!   

最後更新日期: 6/1/2003 6:22:05 PM