簡介
多態(Polymorphism)按字面的意思就是“多種狀態”。在面向對象語言中,接口的多種不同的實現方式即為多態。引用Charlie Calverts對多態的描述——多態性是允許你將父對象設定成為和一個或更多的他的子對象相等的技術,賦值之後,父對象就可以根據當前賦值給它的
![多態](/img/1/f78/nBnauM3X4QTNwQDM3YTOyUDM0QTMwADMwADMwADMwATMxAzL2kzL2EzLt92YucmbvRWdo5Cd0FmLxE2LvoDc0RHa.jpg)
![多態](/img/3/ec5/nBnauM3X1gjNxYDM3YTOyUDM0QTMwADMwADMwADMwATMxAzL2kzL3gzLt92YucmbvRWdo5Cd0FmLzE2LvoDc0RHa.jpg)
子對象的特性以不同的方式運作(摘自“Delphi4 編程技術內幕”)。簡單的說,就是一句話:允許將子類類型的指針賦值給父類類型的指針。多態性在Object Pascal和C++中都是通過虛函式(Virtual Function) 實現的。
形式
多態指同一個實體同時具有多種形式。它是面向對象程式設計(OOP)的一個重要特徵。如果一個語言只支持類而不支持多態,只能說明它是基於對象的,而不是面向對象的。C++中的多態性具體體現在運行和編譯兩個方面。運行時多態是動態多態,其具體引用的對象在運行時才能確定。編譯時多態是靜態多態,在編譯時就可以確定對象使用的形式。
多態:同一操作作用於不同的對象,可以有不同的解釋,產生不同的執行結果。在運行時,可以通過指向基類的指針,來調用實現派生類中的方法。
C++中,實現多態有以下方法:虛函式,抽象類,復蓋,模板(重載和多態無關)。
Oc中的多態:不同對象對同一訊息的不同回響.子類可以重寫父類的方法
多態就是允許方法重名 參數或返回值可以是父類型傳入或返回。
多態也指生物學中腔腸動物的特殊的生活方式。水螅態與水母態的世代交替現象。
作用
把不同的子類對象都當作父類來看,可以禁止不同子類對象之間的差異,寫出通用的代碼,做出通用的編程,以適應需求的不斷變化。
賦值之後,父對象就可以根據當前賦值給它的子對象的特性以不同的方式運作。也就是說,父親的行為像兒子,而不是兒子的行為像父親。
舉個例子:從一個基類中派生,回響一個虛命令,產生不同的結果。
比如從某個基類繼承出多個對象,其基類有一個虛方法Tdoit,然後其子類也有這個方法,但行為不同,然後這些子對象中的任何一個可以賦給其基類對象的引用,或者將子對象地址賦給基類指針,這樣其基類的對象就可以執行不同的操作了。實際上你是在通過其基類來訪問其子對象的,你要做的就是一個賦值操作。
使用繼承性的結果就是可以創建一個類的家族,在認識這個類的家族時,就是把導出類的對象當作基類的對象,這種認識又叫作upcasting。這樣認識的重要性在於:我們可以只針對基類寫出一段程式,但它可以適應於這個類的家族,因為編譯器會自動找出合適的對象來執行操作。這種現象又稱為多態性。而實現多態性的手段又叫稱動態綁定(dynamic binding)。
簡單的說,建立一個父類的對象,它的內容可以是這個父類的,也可以是它的子類的,當子類擁有和父類同樣的函式,當使用這個對象調用這個函式的時候,定義這個對象的類(也就是父類)里的同名函式將被調用,當在父類里的這個函式前加virtual關鍵字,那么子類的同名函式將被調用。通俗點說就是父類不加virtual關鍵字,那么子類的同名函式將會被復蓋。
例子
在C++中:
class A {
public:
A() {}
virtual void foo() {
cout << "This is A." << endl;
}
};
class B : public A {
public:
B() {}
void foo() {
cout << "This is B." << endl;
}
};
int main(int argc, char* argv[]) {
A *a = new B();
a->foo();
if(a != NULL)
delete a;
return 0;
}
這將顯示:
This is B.
如果把virtual去掉,將顯示:
This is A.
前面的多態通過使用虛函式virtual void foo()來實現。
在java中:
多態,是面向對象的程式設計語言最核心的特徵。多態,意味著一個對象有著多重特徵,可以在特定的情況下,表現不同的狀態,從而對應著不同的屬性和方法。從程式設計的角度而言,多態可以這樣來實現(以java語言為例):
public interface Parent {
public void simpleCall();
}
public class Child_A implements Parent{
public void simpleCall(){
//具體的實現細節;
}
}
public class Child_B implements Parent{
public void simpleCall(){
//具體的實現細節;
}
}
//當然還可以有其他的實現
然後,我們就可以看到多態所展示的特性了:
Parent pa = new Child_A();
pa.simpleCall()則顯然是調用Child_A的方法;
Parent pa = new Child_B();
pa.simpleCall()則是在調用Child_B的方法。所以,我們對於抽象的父類或者接口給出了我們的具體實現後,pa 可以完全不用管實現的細節,只訪問我們定義的方法,就可以了。事實上,這就是多態所起的作用,可以實現控制反轉這在大量的J2EE輕量級框架中被用到,比如Spring的依賴注射機制。
例:藪枝螅