深圳網站(zhàn)建設中,我們經常會遇到網站(zhàn)程序各種語言的多态,下面就(jiù)介紹幾點:
多态确切的含義是:同一類的對象收到相(xiàng)同消息時,會得(de)到不同的結果。而這個消息是不可(kě)預測的。多态,顧名思義,就(jiù)是多種狀态,也就(jiù)是多種結果。
以Java爲例,由于Java是強類型語言,因此變量和函數返回值是有狀态的。比如(rú),實現一個add函數的功能,其參數可(kě)能是兩個int型整數,也可(kě)能是兩個float型浮點數,而返回值可(kě)能是整型或者浮點型。在這種情況下,add函數是有狀态的,它有多種可(kě)能的運行結果。在實際使用時,編譯器會自(zì)動匹配适合的那個函數。這屬于函數重載的概念。需要說(shuō)明的是,重載并不是面向對象裡(lǐ)的東西,和多态也不是一個概念,它屬于多态的一種表現形式。
多态性是一種通過多種狀态或階段描述相(xiàng)同對象的編程方式。它的真正意義在于:實際開發中,隻要關心一個接口或基類的編程,而不必關心一個對象所屬于的具體(tǐ)類。
很多地方會看(kàn)到“PHP沒有多态”這種說(shuō)法。事(shì)實上,不是它沒有,而是它本來(lái)就(jiù)是多态的。PHP作(zuò)爲一門(mén)腳本語言,自(zì)身(shēn)就(jiù)是多态的,所以在語言這個級别上,不談PHP的多态。在PHP官方手冊也找不到對多态的詳細描述。
既然說(shuō)PHP沒有多态這個概念(實際上是不需要多态這個概念),那爲
什麽又要講多态呢(ne)?可(kě)以看(kàn)下面的例子,如(rú)下所示:
<?php
class employee{
protected function working(){
echo'本方法需重載才能運行';
}
}
class teacher extends employee{
public function working(){
echo'教書(shū)';
}
}
class coder extends employee{
public function working(){
echo'敲代碼';
}
}
function doprint($obj){
if(get_class($obj)=='employee'){
echo'Error';
}else{
$obj->working();
}
}
doprint(new teacher());
doprint(new coder());
doprint(new employee());
通過判斷傳入的對象所屬的類不同來(lái)調用其同名方法,得(de)出不同結果,這是多态嗎(ma)?如(rú)果站(zhàn)在C++角度,這不是多态,這隻是不同類對象的不同表現而已。C++裡(lǐ)的多态指運行時對象的具體(tǐ)化,指同一類對象調用相(xiàng)同的方法而返回不同的結果。看(kàn)個C++的例子,如(rú)下所示:
#include<cstdlib>
#include<iostream>
/**
C++中用虛函數實現多态
*/
using namespace std;
class father{
public:
father():age(30){cout<<"父類構造法,年(nián)齡"<<age<<"\n";}
~father(){cout<<"父類析構"<<"\n";}
void eat(){cout<<"父類吃(chī)飯吃(chī)三斤"<<"\n";}
virtual void run(){cout<<"父類跑10000米"<<"\n";}//虛函數
protected:
int age;
};
class son:public father{
public:
son(){cout<<"子類構造法"<<"\n";}
~son(){cout<<"子類析構"<<"\n";}
void eat(){cout<<"兒子吃(chī)飯吃(chī)一斤"<<"\n";}
void run(){cout<<"兒子跑100米"<<"\n";}
void cry(){cout<<"哭泣"<<"\n";}
};
int main(int argc,char*argv[])
{
father*pf=new son;
pf->eat();
pf->run();
delete pf;
system("PAUSE");
return EXIT_SUCCESS;
}
上面的代碼首先定義一個父類,然後定義一個子類,這個子類繼承父類的一些方法并且有自(zì)己的方法。通過father*pf=new son;語句創建一個派生(shēng)類(子類)對象,并且把該派生(shēng)類對象賦給基類(父類)指針,然後用該指針訪問(wèn)父類中的eat和run方法。下圖所示是運行結果。
由于父類中的run方法加了virtual關鍵字,表示該函數有多種形态,可(kě)能被多個對象所擁有。也就(jiù)是說(shuō),多個對象在調用同一名字的函數時會産生(shēng)不同的效果。
這個例子和PHP的例子有什麽不同呢(ne)?C++的這個例子所創建的對象是一個指向父類的子對象,還(hái)可(kě)以創建更多派生(shēng)類對象,然後上轉型爲父類對象。這些對象,都(dōu)是同一類對象,但(dàn)是在運行時,卻都(dōu)能調用到派生(shēng)類同名函數。而PHP中的例子則是不同類的對象調用。
由于PHP是弱類型的,并且也沒有對象轉型機(jī)制,所以不能像C++或者Java那樣實現father$pf=new son;把派生(shēng)類對象賦給基類對象,然後在調用函數時動态改變其指向。在PHP的例子中,對象都(dōu)是确定的,是不同類的對象。所以,從(cóng)這個角度講,這還(hái)不是真正的多态。
通過判斷對象的類屬性實現“多态”,此外,還(hái)可(kě)以通過接口實現多态,如(rú)下所示:
<?php
interface employee{
public function working();
}
class teacher implements employee{
public function working(){
echo'教書(shū)';
}
}
class coder implements employee{
public function working(){
echo'敲代碼';
}
}
function doprint(employee$i){
$i$i->working();
}
$a=new teacher;
$b=new coder;
doprint($a);
doprint($b);
這是多态嗎(ma)?這段代碼和代碼清單1-8相(xiàng)比沒有多少區别,不過這段代碼中doprint函數的參數是一個接口類型的變量,符合“同一類型,不同結果”這一條件(jiàn),具有多态性的一般特征。因此,這是多态。
如(rú)果把代碼清單1-8中doprint函數的obj參數看(kàn)做一種類型(把所有弱類型看(kàn)做一種類型),那就(jiù)可(kě)以認爲代碼清單1-8中的代碼也是一種多态。
再次把三段代碼放(fàng)在一起品味,可(kě)以看(kàn)出:區别是否是多态的關鍵在于看(kàn)對象是否屬于同一類型。如(rú)果把它們看(kàn)做同一種類型,調用相(xiàng)同的函數,返回了不同的結果,那麽它就(jiù)是多态;否則,不能稱其爲多态。由此可(kě)見(jiàn),弱類型的PHP裡(lǐ)多态和傳統強類型語言裡(lǐ)的多态在實現和概念上是有一些區别的,而且弱類型語言實現起多态來(lái)會更簡單,更靈活。
本節解決了什麽是多态,什麽不是多态的問(wèn)題。至于多态是怎麽實現的,各種語言的策略是不一樣的。但(dàn)是,最終的實現無非就(jiù)是查表和判斷。總結如(rú)下:
多态指同一類對象在運行時的具體(tǐ)化。
PHP語言是弱類型的,實現多态更簡單、更靈活。
類型轉換不是多态。
PHP中父類和子類看(kàn)做“繼父”和“繼子”關系,它們存在繼承關系,但(dàn)不存在血緣關系。因此子類無法向上轉型爲父類,從(cóng)而失去(qù)多态最典型的特征。
多态的本質就(jiù)是if…else,隻不過實現的層級不同。
本站(zhàn)文章(zhāng)爲深圳網站(zhàn)建設·源美網絡原創策劃,如(rú)有版權糾紛或者違規問(wèn)題,請(qǐng)聯系我們删除,謝謝!
上一篇: 對PHP接口的思考
下一篇: 魔術(shù)方法的應用
售後保障
承諾任何問(wèn)題1小時内解決數據備份
更安全、更高效、更穩定價格公道精準
項目經理(lǐ)精準報價不弄虛作(zuò)假合作(zuò)無風(fēng)險
重合同講信譽,無效全額退款