分(fēn)享到:

在網站(zhàn)制作(zuò)中各種語言中的多态

日(rì)期:2016-10-25 21:06:00     閱讀(dú):500     文章(zhāng)來(lái)源:源美網絡     标簽:深圳網站(zhàn)建設,PHP語言

深圳網站(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方法。下圖所示是運行結果。

blob.png

由于父類中的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āng)引用:

本站(zhàn)文章(zhāng)爲深圳網站(zhàn)建設·源美網絡原創策劃,如(rú)有版權糾紛或者違規問(wèn)題,請(qǐng)聯系我們删除,謝謝!

上一篇: 對PHP接口的思考

下一篇: 魔術(shù)方法的應用

返回列表
最新案例
OUR ADVANTAGE WORKS

售後保障

承諾任何問(wèn)題1小時内解決

數據備份

更安全、更高效、更穩定

價格公道精準

項目經理(lǐ)精準報價不弄虛作(zuò)假

合作(zuò)無風(fēng)險

重合同講信譽,無效全額退款