面向?qū)ο缶幊痰母拍顚?duì)每一個(gè)作者來(lái)說(shuō)都有不同的看法,我提醒一下一個(gè)面向?qū)ο笳Z(yǔ)言應(yīng)有的東西: " /> 亚洲五月六月丁香激情,亚洲精美色品网站,久久黄色级2电影

色尼玛亚洲综合影院,亚洲3atv精品一区二区三区,麻豆freexxxx性91精品,欧美在线91

PHP 中的面向?qū)ο缶幊蹋和ㄏ虼笮?PHP 工程的辦法

這篇文章介紹在 php 的面向?qū)ο缶幊蹋∣OP)。我將演示如何用面向?qū)ο蟮母拍罹幊鲚^少的代碼但更好的程序。祝大家好運(yùn)。  

  面向?qū)ο缶幊痰母拍顚?duì)每一個(gè)作者來(lái)說(shuō)都有不同的看法,我提醒一下一個(gè)面向?qū)ο笳Z(yǔ)言應(yīng)有的東西: 
- 數(shù)據(jù)抽象和信息隱藏 
- 繼承 
- 多態(tài)性 

  在php中使用類進(jìn)行封裝的辦法: 

<?php 
class Something { 
    // In OOP classes are usually named starting with a cap letter. 
    var $x; 

    function setX($v) { 
        // Methods start in lowercase then use lowercase to seprate 
        // words in the method name example getValueOfArea() 
        $this->x=$v; 
    } 

    function getX() { 
        return $this->x; 
    } 

?>

  當(dāng)然你可以用你自己的辦法,但有一個(gè)標(biāo)準(zhǔn)總是好的。 

  php 中類的數(shù)據(jù)成員使用 "var" 定義,數(shù)據(jù)成員是沒(méi)有類型直到被賦值。一個(gè)數(shù)據(jù)成員可能是一個(gè) integer、數(shù)組、聯(lián)合數(shù)組 (associative array) 或甚至對(duì)象(object). 方法在類里定義成函數(shù),在方法里存取數(shù)據(jù)成員,你必須使用 $this->name 這樣的辦法,否則對(duì)方法來(lái)說(shuō)是一個(gè)函數(shù)的局部變量。 

  使用 new 來(lái)創(chuàng)建一個(gè)對(duì)象 

$obj = new Something; 

然后使用成員函數(shù) 

$obj->setX(5); 
$see = $obj->getX(); 

  setX 成員函數(shù)將 5 賦給對(duì)象(而不是類)obj 中成員變量, 然后 getX 返回值 5. 

  你也可以用對(duì)象引用來(lái)存取成員變量,例如:$obj->x=6; 然而,這不一種好的面向?qū)ο缶幊痰姆椒āN覉?jiān)持你應(yīng)使用成員函數(shù)來(lái)設(shè)置成員變量的值和通過(guò)成員函數(shù)來(lái)讀取成員變量。如果你認(rèn)為成員變量是不可存取的除了使用成員函數(shù)的辦法,你將成為一個(gè)好的面向?qū)ο蟪绦騿T。但不幸的是 php 本身沒(méi)有辦法聲明一個(gè)變量是私有的,所以允許糟糕的代碼存在。 

  在 php 中繼承使用 extend 來(lái)聲明。 


<?php 
class Another extends Something { 
    var $y; 
    function setY($v) { 
        // Methods start in lowercase then use lowercase to seperate 
        // words in the method name example getValueOfArea() 
        $this->y=$v; 
    } 

    function getY() { 
        return $this->y; 
    } 

?> 

  這樣類 "Another" 的對(duì)象擁有父類的所用成員變量及方法函數(shù),再加上自己 
的成員變量及成員函數(shù)。如: 

$obj2=new Another; 
$obj2->setX(6); 
$obj2->setY(7); 

  多重繼承不被支持,所以你不能讓一個(gè)類繼承多個(gè)類。 

  在繼承類中你可以重新定義來(lái)重定義方法,如果我們?cè)?nbsp;"Another" 重新定義 getX,那么我們不再能存取 "Something" 中的成員函數(shù) getX. 同樣,如果我們?cè)诶^承類中聲明一個(gè)和父類同名的成員變量,那么繼承類的變量將隱藏父類的同名變量。

  你可以定義一個(gè)類的構(gòu)造函數(shù), 構(gòu)造函數(shù)是和類同名的成員函數(shù),在你創(chuàng)建類的對(duì)象時(shí)被調(diào)用。 


<?php 
class Something { 
    var $x; 

    function Something($y) { 
        $this->x=$y; 
    } 

    function setX($v) { 
        $this->x=$v; 
    } 

    function getX() { 
        return $this->x; 
    } 

?> 

  所以可以用如下方法創(chuàng)建對(duì)象: 

$obj=new Something(6); 

  構(gòu)造函數(shù)自動(dòng)賦值 5 給成員變量 x,構(gòu)造函數(shù)和成員函數(shù)都是普通的php函數(shù),所以你可以使用缺省參數(shù)。 

function Something($x="3",$y="5") 

然后: 

$obj=new Something(); // x=3 and y=5 
$obj=new Something(8); // x=8 and y=5 
$obj=new Something(8,9); // x=8 and y=9 

  缺省參數(shù)的定義方法和 C++ 一樣,因此你不能傳一個(gè)值給 Y 但讓 X 取缺省值,實(shí)參的傳遞是從左到右,當(dāng)沒(méi)有更多的實(shí)參時(shí)函數(shù)將使用缺省參數(shù)。 

  只有當(dāng)繼承類的構(gòu)造函數(shù)被調(diào)用后,繼承類的對(duì)象才被創(chuàng)建,父類的構(gòu)造函數(shù)沒(méi)有被調(diào)用,這是php不同其他面向?qū)ο笳Z(yǔ)言的特點(diǎn),因?yàn)闃?gòu)造函數(shù)調(diào)用鏈?zhǔn)敲嫦驅(qū)ο缶幊痰奶攸c(diǎn)。如果你想調(diào)用基類的構(gòu)造函數(shù),你不得不在繼承類的構(gòu)造函數(shù)中顯式調(diào)用它。這樣它能工作是因?yàn)樵诶^承類中父類的方法全部可用。 

<?php 
function Another() { 
    $this->y=5; 
    $this->Something(); //explicit call to base class constructor. 

?>

  在面向?qū)ο缶幊讨幸环N好的機(jī)制是使用抽象類,抽象類是一種不能實(shí)例化而是用來(lái)給繼承類定義界面的類。設(shè)計(jì)師經(jīng)常使用抽象類來(lái)強(qiáng)制程序員只能從特定的基類來(lái)繼承,所以就能確定新類有所需的功能,但在php中沒(méi)有標(biāo)準(zhǔn)的辦法做到這一點(diǎn),不過(guò): 
  如果你在定義基類是需要這個(gè)特點(diǎn),可以通過(guò)在構(gòu)造函數(shù)中調(diào)用 "die",這樣你就可以確保它不能實(shí)例化,現(xiàn)在定義抽象類的函數(shù)并在每個(gè)函數(shù)中調(diào)用 "die",如果在繼承類中程序員不想重定義而直接調(diào)用基類的函數(shù),將會(huì)產(chǎn)生一個(gè)錯(cuò)誤。此外,你需要確信因?yàn)?a href=/itjie/phpjishu/ target=_blank class=infotextkey>php沒(méi)有類型,有些對(duì)象是從基類繼承而來(lái)的繼承類創(chuàng)建的,因此增加一個(gè)方法在基類來(lái)辨別類(返回 "一些標(biāo)識(shí)")并驗(yàn)證這一點(diǎn),當(dāng)你收到一個(gè)對(duì)象作為參數(shù)派上用場(chǎng)。 但對(duì)于一個(gè)惡棍程序沒(méi)用辦法,因?yàn)樗梢栽诶^承類中重定義此函數(shù),通常這種辦法只對(duì)懶惰的程序員奏效。當(dāng)然,最好的辦法是防止程序接觸到基類的代碼只提供界面。 

  重載在php中不被支持。在面向?qū)ο缶幊讨心憧梢酝ㄟ^(guò)定義不同參數(shù)種類和多少來(lái)重載一個(gè)同名成員函數(shù)。php是一種松散的類型語(yǔ)言,所以參數(shù)類型重載是沒(méi)有用的,同樣參數(shù)個(gè)數(shù)不同的辦法重載也不能工作。 

  有時(shí)候,在面向?qū)ο缶幊讨兄剌d構(gòu)造函數(shù)很有用,所以你能以不同的方式創(chuàng)建不同的對(duì)象(通過(guò)傳遞不同的參數(shù)個(gè)數(shù))。一個(gè)小巧門(mén)可以做到這一點(diǎn): 

<?php 
class Myclass { 
    function Myclass() { 
        $name="Myclass".func_num_args(); 
        $this->$name(); 
        //Note that $this->$name() is usually wrong but here 
        //$name is a string with the name of the method to call. 
    } 

    function Myclass1($x) { 
        code; 
    } 

    function Myclass2($x,$y) { 
        code; 
    } 

?>

  通過(guò)這種辦法可以部分達(dá)到重載的目的。 

$obj1=new Myclass(1); //Will call Myclass1 
$obj2=new Myclass(1,2); //Will call Myclass2 

  感覺(jué)還不錯(cuò)! 

多態(tài)性 

  多態(tài)性被定義為當(dāng)在運(yùn)行時(shí)刻一個(gè)對(duì)象作為參數(shù)傳遞時(shí),對(duì)象能決定調(diào)用那個(gè)方法的能力。例如,用一個(gè)類定義了方法 "draw",繼承類重定義 "draw" 的行為來(lái)畫(huà)圓或正方形,這樣你就有一個(gè)參數(shù)為 x 的函數(shù),在函數(shù)里可以調(diào)用 $x->draw(). 如果支持多態(tài)性,那么 "draw" 方法的調(diào)用就取決于對(duì)象 x 的類型。多態(tài)性在php中很自然被支持(想一想這種情況在C++編譯器中如果編譯,那一個(gè)方法被調(diào)用?然而你不知道對(duì)象的類型是什么,當(dāng)然現(xiàn)在不是這種情況)。幸好php支持多態(tài)性。 

<?php 
function niceDrawing($x) { 
    //Supose this is a method of the class Board. 
    $x->draw(); 


$obj=new Circle(3,187); 
$obj2=new Rectangle(4,5); 

$board->niceDrawing($obj); //will call the draw method of Circle. 
$board->niceDrawing($obj2); //will call the draw method of Rectangle. 
?> 

php 的面向?qū)ο缶幊?nbsp;

  純對(duì)象論者認(rèn)為php不是真正的面向?qū)ο笳Z(yǔ)言,這是對(duì)的。php是一種混合語(yǔ)言,你可以用面向?qū)ο蠡騻鹘y(tǒng)結(jié)構(gòu)編程的方法來(lái)使用它。對(duì)于大型工程,然而你可能或需要使用純面向?qū)ο蠓椒▉?lái)定義類,并在你的工程中只使用對(duì)象和類。越來(lái)越大的工程通過(guò)使用面向?qū)ο蟮姆椒〞?huì)獲得益處,面向?qū)ο蠊こ谭浅H菀拙S持,容易理解并且重用。這是軟件工程的基本。使用這些概念在網(wǎng)站設(shè)計(jì)中是未來(lái)成功的關(guān)鍵。 

php中的高級(jí)面向?qū)ο蠹夹g(shù) 

  在回顧面向?qū)ο蟮幕靖拍钪螅覍⒔榻B一些更高級(jí)的技術(shù)。 

串行化 

  php并不支持持久性對(duì)象,在面向?qū)ο笳Z(yǔ)言中持久性對(duì)象是一些經(jīng)過(guò)應(yīng)用程序多次調(diào)用仍然保持其狀態(tài)和功能的對(duì)象,這意味著有一種能保存對(duì)象到文件或數(shù)據(jù)庫(kù)中然后重新裝載對(duì)象。這種機(jī)制稱之為串行化。php 有一個(gè)串行化函數(shù),可以在對(duì)象中調(diào)用,串行化函數(shù)返回一個(gè)字符串代表這個(gè)對(duì)象。然后串行化函數(shù)保存的是成員數(shù)據(jù)而不是成員函數(shù)。 

  在php4中,如果你串行化一個(gè)對(duì)象到字符串 $s, 然后刪除此對(duì)象,再反串行化對(duì)象到 $obj,你仍然可以調(diào)用對(duì)象的方法函數(shù)。但我不推薦這種方法,這因?yàn)?nbsp;(a) 這種功能在將來(lái)不一定支持(b)這導(dǎo)致一種幻象,如果你保存串行化對(duì)象到磁盤(pán)并退出程序。將來(lái)重新運(yùn)行此腳本時(shí)你不能反串行化此對(duì)象并希望對(duì)象的方法函數(shù)仍有效,因?yàn)榇谢鰜?lái)的字符串并沒(méi)有表示任何成員函數(shù)。最后,串行化保存對(duì)象的成員變量在php中非常有用,僅僅如此. (你可以串行化聯(lián)合數(shù)組和數(shù)組到磁盤(pán)里)。 

例子: 

<?php 
$obj=new Classfoo(); 
$str=serialize($obj); 
// Save $str to disk 

//...some months later 

//Load str from disk 
$obj2=unserialize($str) 
?> 

  上例中,你可以恢復(fù)成員變量而沒(méi)有成員函數(shù)(根據(jù)文檔)。這導(dǎo)致 $obj2->x 是 
唯一的方法來(lái)存取成員變量(因?yàn)闆](méi)有成員函數(shù))。 

  這里還有一些方法解決這個(gè)問(wèn)題,但我留下給你因?yàn)樗鼤?huì)搞臟這個(gè)干凈的文檔。
我希望php將來(lái)能全面支持串行化。 

使用類來(lái)操縱保存的數(shù)據(jù) 

  php 和面向?qū)ο缶幊讨幸粋€(gè)比較好的地方是你很容易定義類來(lái)操縱某些東西,并且當(dāng)需要時(shí)調(diào)用合適的類。假設(shè)有一個(gè)HTML文件,你需要通過(guò)選擇產(chǎn)品的 ID 號(hào)來(lái)選擇一個(gè)產(chǎn)品,你的數(shù)據(jù)保存在數(shù)據(jù)庫(kù)中,而你想顯示產(chǎn)品的信息,如價(jià)格等等。你有不同種類的產(chǎn)品,同樣的動(dòng)作對(duì)不同的產(chǎn)品有不同的含義。例如,顯示一個(gè)聲音意味著播放它,而對(duì)其他產(chǎn)品來(lái)說(shuō)可能是顯示一個(gè)存儲(chǔ)在數(shù)據(jù)庫(kù)的圖片。你可以用面向?qū)ο缶幊毯?a href=/itjie/phpjishu/ target=_blank class=infotextkey>php來(lái)達(dá)到,代碼少但更好。 

  定義一個(gè)類,定義類應(yīng)該有的方法,然后通過(guò)繼承來(lái)定義每一種產(chǎn)品的類(SoundItem類, ViewableItem類,等等),重定義每個(gè)產(chǎn)品類的方法,使它們?nèi)缒闼琛8鶕?jù)你保存在數(shù)據(jù)庫(kù)中的表的產(chǎn)品類型字段來(lái)給每一種產(chǎn)品類型定義一個(gè)類,一個(gè)典型的產(chǎn)品表應(yīng)有字段(id, 類型, 價(jià)格, 描述,等等)。在腳本中你從數(shù)據(jù)庫(kù)的表中獲取類型信息,然后實(shí)例化相應(yīng)類的對(duì)象: 

<?php 
$obj=new $type(); 
$obj->action(); 
?> 

  這是php比較的特性,你可以調(diào)用 $obj 的顯示方法或其他方法而不用去管對(duì)象的類型。通過(guò)這種技術(shù),當(dāng)你增加一種新類型的對(duì)象時(shí),你不需要去修改腳本。這個(gè)方法有點(diǎn)威力,就是定義所有對(duì)象應(yīng)有的方法而不管它的類型,然后在不同的類中以不同的方式來(lái)實(shí)現(xiàn),這樣就可以在腳本中對(duì)不同的類型對(duì)象使用他們,再?zèng)]有 if, 沒(méi)有兩個(gè)程序員在同一個(gè)文件里,永遠(yuǎn)快樂(lè)。你相信編程是這樣快樂(lè)不?維護(hù)代價(jià)小并且可重用? 

  如果你帶領(lǐng)一組程序員,最好的方法是劃分任務(wù),每人可以對(duì)某種類和對(duì)象負(fù)責(zé)。國(guó)際化可以用同樣的技術(shù)解決,使合適的類對(duì)應(yīng)使用者選擇的不同的語(yǔ)言等等。 

復(fù)制和克隆 

  當(dāng)你創(chuàng)建一個(gè)對(duì)象 $obj, 你可以使用 $obj2 = $obj 來(lái)拷貝一個(gè)對(duì)象,新的對(duì)象是 $obj 的一個(gè)拷貝(不是引用),所以在賦值完新對(duì)象有 $obj 同新的狀態(tài)。有時(shí)候你不想這樣,只想創(chuàng)建和 obj 同樣的新對(duì)象,調(diào)用新對(duì)象的構(gòu)造函數(shù)如同你曾使用過(guò) new 命令。這可以通過(guò)php的串行化和使用基類并且其他類必須從基類繼承來(lái)達(dá)到。 


進(jìn)行危險(xiǎn)的地帶 

  當(dāng)你串行化一個(gè)對(duì)象,你得到一個(gè)有特定格式的字符串,如果你有好奇心,可能你會(huì)探尋其中的秘密,字符串中有一個(gè)東西就是類的名字,你可以解開(kāi)它: 

<?php 
$herring = serialize($obj); 
$vec = explode(":",$herring); 
$nam = str_replace("/"", "", $vec[2]); 
?> 

  假設(shè)你創(chuàng)建一個(gè)類 "Universe" 并且使所有類都從 "Universe" 繼承而來(lái),你可以在 "Universe" 定義一個(gè)克隆的方法: 

<?php 
class Universe { 
    function __clone() { 
        $herring=serialize($this); 
        $vec=explode(":",$herring); 
        $nam=str_replace("/"", "",$vec[2]); 
        $ret= new $nam; 
        return $ret; 
    } 


//Then: 

$obj=new Something(); 
//Something extends Universe !! 
$other=$obj->__clone(); 
?> 

  你所得的是類 Something 的新對(duì)象如同使用 new 一樣,并且構(gòu)造函數(shù)被調(diào)用等等。我不知道這對(duì)你是不是有用,這是一個(gè)很好的實(shí)踐,Universe 類知道它的繼承類的名字。對(duì)你來(lái)說(shuō),唯一的限制是你的想象力!!! 

  注意:我使用的是php4, 文章里有些東西可能不適合php3。 

-結(jié)束- 

php技術(shù)PHP 中的面向?qū)ο缶幊蹋和ㄏ虼笮?PHP 工程的辦法,轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 平远县| 卓尼县| 吐鲁番市| 冕宁县| 诏安县| 藁城市| 宁海县| 自贡市| 日土县| 延边| 九江市| 东莞市| 文昌市| 桑植县| 北海市| 苏州市| 常州市| 和政县| 荆州市| 松滋市| 台东县| 清远市| 开鲁县| 洛隆县| 商河县| 塔城市| 章丘市| 汉川市| 金川县| 定西市| 翁源县| 九龙坡区| 渝北区| 浏阳市| 开封市| 微山县| 山西省| 洛南县| 渝北区| 东城区| 浏阳市|