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