多型性是物件導向程式設計的乙個重要特性。如果乙個語言只支援類而不支援多型,是不能稱為物件導向語言的,只能說是基於物件的。
多型性
一、定義
好多書上寫的比較字面的解釋是:向不同的物件傳送同乙個訊息,不同的物件在接收時會產生不同的行為。但是這讀起來總感覺很難理解。
我對它的理解就是:通過不同的物件在呼叫乙個同名函式時,會產生不同的功能。當然這個同名函式本身是具有不同功能的。
二、分類
靜態多型:
編譯器在編譯期間完成的,編譯器根據函式實參的型別(可能會進行隱式型別轉換),可推斷出要呼叫那個函式,如果有對應的函式就呼叫該函式,否則出現編譯錯誤。
比如乙個簡單的函式過載:
int add(int l,int r)
float add(float l, float r)
int main()
動態多型:
不在編譯時確定呼叫的那個函式,而是在程式執行時動態的確定物件的型別是,然後根據實際型別呼叫相應的方法。動態的多型性就是通過虛函式的實現的。
在這裡有必要介紹一下什麼是靜態繫結(早繫結)和動態繫結(晚繫結):在編譯器編譯期間就可以確定函式的呼叫位址,是靜態的,就是說位址是早繫結的。而如果函式呼叫的位址不能在編譯器期間確定,需要在執行時才確定,這就屬於晚繫結,此時是將虛函式和對應的物件繫結在一起。
動態繫結的條件
1.必須是將物件和虛函式繫結
2.通過基類的指標或者引用來呼叫乙個新物件
使用virtual關鍵字修飾函式時,指明該函式為虛函式,派生類需要重新實現,編譯器將實現動態繫結。
class base
};class derived :public base
};int main()
執行結果:
這就是動態多型性通過虛函式的實現,通過指向不同物件的基類指標pb呼叫同乙個同名函式,從而實現不同的功能。
三、函式過載、同名隱藏和覆蓋(重寫)
之前已經了解過函式過載和同名隱藏,在多型中又出現了一種新的同名型別——覆蓋(也稱作重寫),那麼在類的繼承體系中他們三個同名函式的區別到底是什麼。
class base
void add(float l, float r) //過載,屬於同一作用域
void test1(int t1)
virtual void test2(int t1)
virtual void display() };
class derived :public base
virtual void test2(int t1,int t2) //隱藏,基類中有virtual關鍵字,引數不同
virtual void display() //覆蓋,基類中有virtual關鍵字,引數相同
};
純虛函式一、定義
純虛函式是指在基類中宣告時被初始化為0的函式。純虛函式在基類中沒有定義,要求在派生類中實現。
二、一般形式
virtual 函式型別 函式名(引數列表)=0;
三、注意
1.純虛函式沒有函式體。
2.最後面的「=0」不表示函式返回值為0,只是告訴編譯系統該函式為純虛函式。
四、抽象類
含有純虛函式的類叫做抽象類,抽象類不能用來定義物件(不能例項化)。 注意
抽象類不能定義物件,但是可以定義指向抽象類資料的指標。
如果在派生類中沒有對純虛函式定義,則這個派生類也是抽象類,不能用來定義物件。
總結
1、派生類重寫基類的虛函式實現多型,要求函式名、引數列表、返回值完全相同。(協變除外)
2、基類中定義了虛函式,在派生類中該函式始終保持虛函式的特性。
派生類中函式名的前邊可以不加virtual關鍵字。
3、只有類的成員函式才能定義為虛函式,靜態成員函式不能定義為虛函式。
靜態成員函式是屬於類的物件公有的,沒有this指標,不能實現動態繫結。
4、如果在類外定義虛函式,只能在宣告函式時加virtual關鍵字,定義時不用加。
5、建構函式不能定義為虛函式,雖然可以將operator=定義為虛函式,但最好不要這麼做,使用時容
易混淆。
虛函式的訪問是通過虛表來實現的,在物件未建立完成之前,無法將虛表指標填進物件中,從而無法完成虛函式的訪問。
賦值運算子本來是用來進行同型別物件的賦值,然而不同型別的函式也可以定義為虛函式,所有會出現型別二義性問題。
6、不要在建構函式和析構函式中呼叫虛函式,在建構函式和析構函式中,物件是不完整的,可能會
出現未定義的行為。
7、最好將基類的析構函式宣告為虛函式。(析構函式比較特殊,因為派生類的析構函式跟基類的析構
函式名稱不一樣,但是構成覆蓋,這裡編譯器做了特殊處理)
避免記憶體洩露的問題。如果基類和派生類中都有動態開闢記憶體,在不將析構函式宣告為虛函式的前提下,系統只會釋放基類中動態開闢的空間,而忽略派生類中動態開闢的空間。通過將基類的析構函式宣告為虛函式可以解決。
物件導向程式設計 多型性
include iostream using namespace std class b0 int main 輸出 b1 display d1 display 示例3 include using namespace std class b0 基類b0宣告 void main 主函式 輸出 b0 di...
python之物件導向程式設計之多型與多型性
1.什麼是多型 多型指的是同一種事物的多種形態 水 冰 水蒸氣 液態水 動物 人 狗 豬 2.為啥要用多型 多型性 繼承同乙個類的多個子類中有相同的方法名 那麼子類產生的物件就可以不用考慮具體的型別而直接呼叫功能 多型性的優點 1.增加了程式的靈活性 以不變應萬變,不論物件千變萬化,使用者都是同一種...
物件導向特性 C 多型性
1.多型性是物件導向程式設計的關鍵技術之一。2.利用多型性技術,可以呼叫同乙個函式名的函式,實現完全不同的功能。3.c 中有兩種多型性 編譯時的多型性和執行時的多型性。編譯時的多型性 通過函式的過載的運算子的過載來實現 函式過載是根據函式呼叫時所給的實參型別和數量,在程式執行前就知道應該呼叫哪乙個函...