欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
PHP中實(shí)現面向對象編程
這篇文章介紹在PHP的面向對象編程(OOP)。我將演示如何用面向對象的概念編出較少的代碼但更好的程序。祝大家好運。
面向對象編程的概念對每一個(gè)作者來(lái)說(shuō)都有不同的看法,我提醒一下一個(gè)面向對象語(yǔ)言應有的東西:
- 數據抽象和信息隱藏
- 繼承
- 多態(tài)性
在PHP中使用類(lèi)進(jìn)行封裝的辦法:
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;
}
}
當然你可以用你自己的辦法,但有一個(gè)標準總是好的。
PHP中類(lèi)的數據成員使用 "var" 定義,數據成員是沒(méi)有類(lèi)型直到被賦值。一個(gè)數據成員可能是一個(gè) integer、數組、聯(lián)合數組(associative array)或甚至對象(object). 方法在類(lèi)里定義成函數,在方法里存取數據成員,你必須使用$this->name 這樣的辦法,否則對方法來(lái)說(shuō)是一個(gè)函數的局部變量。
使用 new 來(lái)創(chuàng )建一個(gè)對象
$obj = new Something;
然后使用成員函數
$obj->setX(5);
$see = $obj->getX();
setX 成員函數將 5 賦給對象(而不是類(lèi))obj 中成員變量, 然后 getX 返回值 5.
你也可以用對象引用來(lái)存取成員變量,例如:$obj->x=6; 然而,這不一種好的面向對象編程的方法。我堅持你應使用成員函數來(lái)設置成員變量的值和通過(guò)成員函數來(lái)讀取成員變量。如果你認為成員變量是不可存取的除了使用成員函數的辦法,你將成為一個(gè)好的面向對象程序員。 但不幸的是PHP本身沒(méi)有辦法聲明一個(gè)變量是私有的,所以允許糟糕的代碼存在。
在 PHP 中繼承使用 extend 來(lái)聲明。
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;
}
}
這樣類(lèi) "Another" 的對象擁有父類(lèi)的所用成員變量及方法函數,再加上自己的成員變量及成員函數。如:
$obj2=new Another;
$obj2->setX(6);
$obj2->setY(7);
多重繼承不被支持,所以你不能讓一個(gè)類(lèi)繼承多個(gè)類(lèi)。
在繼承類(lèi)中你可以重新定義來(lái)重定義方法,如果我們在 "Another" 重新定義 getX,那么我們不再能存取 "Something" 中的成員函數 getX. 同樣,如果我們在繼承類(lèi)中聲明一個(gè)和父類(lèi)同名的成員變量,那么繼承類(lèi)的變量將隱藏父類(lèi)的同名變量。
你可以定義一個(gè)類(lèi)的構造函數, 構造函數是和類(lèi)同名的成員函數,在你創(chuàng )建類(lèi)的對象時(shí)被調用。
class Something {
var $x;
function Something($y) {
$this->x=$y;
}
function setX($v) {
$this->x=$v;
}
function getX() {
return $this->x;
}
}
所以可以用如下方法創(chuàng )建對象:
$obj=new Something(6);
構造函數自動(dòng)賦值 5 給成員變量 x, 構造函數和成員函數都是普通的PHP函數,所以你可以使用缺省參數。
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
缺省參數的定義方法和 C++ 一樣,因此你不能傳一個(gè)值給 Y 但讓 X 取缺省值,實(shí)參的傳遞是從左到右,當沒(méi)有更多的實(shí)參時(shí)函數將使用缺省參數。
只有當繼承類(lèi)的構造函數被調用后,繼承類(lèi)的對象才被創(chuàng )建,父類(lèi)的構造函數沒(méi)有被調用,這是PHP不同其他面向對象語(yǔ)言的特點(diǎn),因為構造函數調用鏈是面向對象編程的特點(diǎn)。如果你想調用基類(lèi)的構造函數,你不得不在繼承類(lèi)的構造函數中顯式調用它。這樣它能工作是因為在繼承類(lèi)中父類(lèi)的方法全部可用。
function Another() {
$this->y=5;
$this->Something(); //explicit call to base class constructor.
}
在面向對象編程中一種好的機制是使用抽象類(lèi),抽象類(lèi)是一種不能實(shí)例化而是用來(lái)給繼承類(lèi)定義界面的類(lèi)。設計師經(jīng)常使用抽象類(lèi)來(lái)強制程序員只能從特定的基類(lèi)來(lái)繼承,所以就能確定新類(lèi)有所需的功能,但在PHP中沒(méi)有標準的辦法做到這一點(diǎn),不過(guò): [page]
如果你在定義基類(lèi)是需要這個(gè)特點(diǎn),可以通過(guò)在構造函數中調用 "die",這樣你就可以確保它不能實(shí)例化,現在定義抽象類(lèi)的函數并在每個(gè)函數中調用 "die",如果在繼承類(lèi)中程序員不想重定義而直接調用基類(lèi)的函數,將會(huì )產(chǎn)生一個(gè)錯誤。
此外,你需要確信因為PHP沒(méi)有類(lèi)型,有些對象是從基類(lèi)繼承而來(lái)的繼承類(lèi)創(chuàng )建的,因此增加一個(gè)方法在基類(lèi)來(lái)辨別類(lèi)(返回 "一些標識")并驗證這一點(diǎn),當你收到一個(gè)對象作為參數派上用場(chǎng)。 但對于一個(gè)惡棍程序沒(méi)用辦法,因為他可以在繼承類(lèi)中重定義此函數,通常這種辦法只對懶惰的程序員奏效。當然,最好的辦法是防止程序接觸到基類(lèi)的代碼只提供界面。
重載在PHP中不被支持。在面向對象編程中你可以通過(guò)定義不同參數種類(lèi)和多少來(lái)重載一個(gè)同名成員函數。PHP是一種松散的類(lèi)型語(yǔ)言,所以參數類(lèi)型重載是沒(méi)有用的,同樣參數個(gè)數不同的辦法重載也不能工作。
有時(shí)候,在面向對象編程中重載構造函數很有用,所以你能以不同的方式創(chuàng )建不同的對象(通過(guò)傳遞不同的參數個(gè)數)。一個(gè)小巧門(mén)可以做到這一點(diǎn):
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ò)這種辦法可以部分達到重載的目的。
$obj1=new Myclass(1); //Will call Myclass1
$obj2=new Myclass(1,2); //Will call Myclass2
感覺(jué)還不錯!
多態(tài)性
多態(tài)性被定義為當在運行時(shí)刻一個(gè)對象作為參數傳遞時(shí),對象能決定調用那個(gè)方法的能力。例如,用一個(gè)類(lèi)定義了方法 "draw",繼承類(lèi)重定義 "draw" 的行為來(lái)畫(huà)圓或正方形,這樣你就有一個(gè)參數為 x 的函數,在函數里可以調用$x->draw(). 如果支持多態(tài)性,那么 "draw" 方法的調用就取決于對象 x 的類(lèi)型。多態(tài)性在PHP中很自然被支持(想一想這種情況在C++編譯器中如果編譯,那一個(gè)方法被調用?然而你不知道對象的類(lèi)型是什么,當然現在不是這種情況)。
幸好PHP支持多態(tài)性。
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的面向對象編程
純對象論者認為PHP不是真正的面向對象語(yǔ)言,這是對的。PHP是一種混合語(yǔ)言,你可以用面向對象或傳統結構編程的方法來(lái)使用它。對于大型工程,然而你可能或需要使用純面向對象方法來(lái)定義類(lèi),并在你的工程中只使用對象和類(lèi)。越來(lái)越大的工程通過(guò)使用面向對象的方法會(huì )獲得益處,面向對象工程非常容易維持,容易理解并且重用。這是軟件工程的基本。使用這些概念在網(wǎng)站設計中是未來(lái)成功的關(guān)鍵。
PHP中的高級面向對象技術(shù)
在回顧面向對象的基本概念之后,我將介紹一些更高級的技術(shù)。
串行化
PHP并不支持持久性對象,在面向對象語(yǔ)言中持久性對象是一些經(jīng)過(guò)應用程序多次調用仍然保持其狀態(tài)和功能的對象,這意味著(zhù)有一種能保存對象到文件或數據庫中然后重新裝載對象。這種機制稱(chēng)之為串行化。PHP 有一個(gè)串行化函數,可以在對象中調用,串行化函數返回一個(gè)字符串代表這個(gè)對象。然后串行化函數保存的是成員數據而不是成員函數。
在PHP4中,如果你串行化一個(gè)對象到字符串 $s, 然后刪除此對象,再反串行化對象到 $obj, 你仍然可以調用對象的方法函數。但我不推薦這種方法,這因為(a)這種功能在將來(lái)不一定支持(b)這導致一種幻象,如果你保存串行化對象到磁盤(pán)并退出程序。將來(lái)重新運行此腳本時(shí)你不能反串行化此對象并希望對象的方法函數仍有效,因為串行化出來(lái)的字符串并沒(méi)有表示任何成員函數。最后,串行化保存對象的成員變量在PHP中非常有用,僅僅如此. (你可以串行化聯(lián)合數組和數組到磁盤(pán)里)。
例子:
$obj=new Classfoo();
$str=serialize($obj);
// Save $str to disk
//...some months later
//Load str from disk
$obj2=unserialize($str)
上例中,你可以恢復成員變量而沒(méi)有成員函數(根據文檔)。這導致 $obj2->x 是唯一的方法來(lái)存取成員變量(因為沒(méi)有成員函數)。
這里還有一些方法解決這個(gè)問(wèn)題,但我留下給你因為它會(huì )搞臟這個(gè)干凈的文檔。
我希望PHP將來(lái)能全面支持串行化。
使用類(lèi)來(lái)操縱保存的數據
PHP和面向對象編程中一個(gè)比較好的地方是你很容易定義類(lèi)來(lái)操縱某些東西,并且當需要時(shí)調用合適的類(lèi)。假設有一個(gè)HTML文件,你需要通過(guò)選擇產(chǎn)品的ID號來(lái)選擇一個(gè)產(chǎn)品,你的數據保存在數據庫中,而你想顯示產(chǎn)品的信息,如價(jià)格等等。你有不同種類(lèi)的產(chǎn)品,同樣的動(dòng)作對不同的產(chǎn)品有不同的含義。
例如,顯示一個(gè)聲音意味著(zhù)播放它,而對其他產(chǎn)品來(lái)說(shuō)可能是顯示一個(gè)存儲在數據庫的圖片。你可以用面向對象編程和PHP來(lái)達到,代碼少但更好。
定義一個(gè)類(lèi),定義類(lèi)應該有的方法,然后通過(guò)繼承來(lái)定義每一種產(chǎn)品的類(lèi)(SoundItem類(lèi), ViewableItem類(lèi),等等),重定義每個(gè)產(chǎn)品類(lèi)的方法,使它們如你所需。根據你保存在數據庫中的表的產(chǎn)品類(lèi)型字段來(lái)給每一種產(chǎn)品類(lèi)型定義一個(gè)類(lèi),一個(gè)典型的產(chǎn)品表應有字段(id, 類(lèi)型, 價(jià)格, 描述,等等)。
在腳本中你從數據庫的表中獲取類(lèi)型信息,然后實(shí)例化相應類(lèi)的對象:
$obj=new $type();
$obj->action();
這是PHP比較的特性,你可以調用 $obj 的顯示方法或其他方法而不用去管對象的類(lèi)型。通過(guò)這種技術(shù),當你增加一種新類(lèi)型的對象時(shí),你不需要去修改腳本。這個(gè)方法有點(diǎn)威力,就是定義所有對象應有的方法而不管它的類(lèi)型,然后在不同的類(lèi)中以不同的方式來(lái)實(shí)現,這樣就可以在腳本中對不同的類(lèi)型對象使用他們,再沒(méi)有 if, 沒(méi)有兩個(gè)程序員在同一個(gè)文件里,永遠快樂(lè )。你相信編程是這樣快樂(lè )不?維護代價(jià)小并且可重用?
如果你帶領(lǐng)一組程序員,最好的方法是劃分任務(wù),每人可以對某種類(lèi)和對象負責。國際化可以用同樣的技術(shù)解決,使合適的類(lèi)對應使用者選擇的不同的語(yǔ)言等等。
復制和克隆
當你創(chuàng )建一個(gè)對象 $obj, 你可以使用 $obj2 = $obj 來(lái)拷貝一個(gè)對象,新的對象是 $obj 的一個(gè)拷貝(不是引用),所以在賦值完新對象有 $obj 同新的狀態(tài)。有時(shí)候你不想這樣,只想創(chuàng )建和 obj 同樣的新對象,調用新對象的構造函數如同你曾使用過(guò) new 命令。這可以通過(guò)PHP的串行化和使用基類(lèi)并且其他類(lèi)必須從基類(lèi)繼承來(lái)達到。
進(jìn)行危險的地帶
當你串行化一個(gè)對象,你得到一個(gè)有特定格式的字符串,如果你有好奇心,可能你會(huì )探尋其中的秘密,字符串中有一個(gè)東西就是類(lèi)的名字,你可以解開(kāi)它:
$herring=serialize($obj);
$vec=explode(:,$herring);
$nam=str_replace("\"",\,$vec[2]);
假設你創(chuàng )建一個(gè)類(lèi) "Universe" 并且使所有類(lèi)都從 "Universe" 繼承而來(lái),你可以在 "Universe" 定義一個(gè)克隆的方法:
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();
你所得的是類(lèi) Something 的新對象如同使用 new 一樣,并且構造函數被調用等等。我不知道這對你是不是有用,這是一個(gè)很好的實(shí)踐,Universe 類(lèi)知道它的繼承類(lèi)的名字。對你來(lái)說(shuō),唯一的限制是你的想象力?。?!
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
c++學(xué)習筆記(六):C++面向對象模型初探
php面向對象詳解
在JavaScript中使用面向對象
PHP 類(lèi)的封裝和使用
在PHP中的面向對象編程
PHP面向對象(1)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久