第八節(jié)--訪問(wèn)方式 <?php class Widget { private $name; private $price; private $id; public function __construct($name, $price) { $this->name = $name; $this->price = floatval($price); $this->id = uniqid(); } //checks if two widgets are the same 檢查兩個(gè)widget是否相同 public function equals($widget) { return(($this->name == $widget->name)AND ($this->price == $widget->price)); } } $w1 = new Widget('Cog', 5.00); $w2 = new Widget('Cog', 5.00); $w3 = new Widget('Gear', 7.00); //TRUE if($w1->equals($w2)) { print("w1 and w2 are the same<br>\n"); } //FALSE if($w1->equals($w3)) { print("w1 and w3 are the same<br>\n"); } //FALSE, == includes id in comparison if($w1 == $w2) //不等,因?yàn)镮D不同 { print("w1 and w2 are the same<br>\n"); } ?> 如果你對(duì)面向?qū)ο缶幊滩皇煜?你可能想知道用private成員的目的是什么. 你可以回憶一下封裝和耦合的想法,這在本章開(kāi)頭我們有討論過(guò). Private成員有助于封裝數(shù)據(jù). 他們可以隱藏在一個(gè)類(lèi)內(nèi)部而不被類(lèi)外部的代碼接觸到. 同時(shí)他們還有助于實(shí)現(xiàn)松散的耦合. 如果數(shù)據(jù)結(jié)構(gòu)外的代碼不能直接訪問(wèn)內(nèi)部屬性,那么就不會(huì)產(chǎn)生一個(gè)隱性的關(guān)聯(lián)性. 當(dāng)然,大部分private屬性仍然可以被外部代碼共享. 解決方法是用一對(duì)public方法,一個(gè)是get(獲取屬性的值),另一個(gè)是set(設(shè)置屬性的值). 構(gòu)造函數(shù)也接受屬性的初始值. 這使得成員間的交流通過(guò)一個(gè)狹窄的,經(jīng)過(guò)良好限定的接口來(lái)進(jìn)行. 這也提供改變傳遞給方法的值的機(jī)會(huì). 注意在例子6.8中,構(gòu)造函數(shù)如何強(qiáng)制使price成為一個(gè)float數(shù)(floadval()). Protected(受保護(hù)的) 成員能被同個(gè)類(lèi)中的所有方法和繼承出的類(lèi)的中所有方法訪問(wèn)到. Public屬性有違封裝的精神,因?yàn)樗鼈冊(cè)试S子類(lèi)依賴(lài)于一個(gè)特定的屬性來(lái)書(shū)寫(xiě).protected方法則不會(huì)帶來(lái)這方面的擔(dān)憂(yōu).一個(gè)使用protected方法的子類(lèi)需要很清楚它的父類(lèi)的結(jié)構(gòu)才行. 例子6.9由例子6.8改進(jìn)而得到,包含了一個(gè)Widget的子類(lèi)Thing. 注意Widget現(xiàn)在有一個(gè)叫作getName的protected方法. 如果Widget的實(shí)例試圖調(diào)用protected方法將會(huì)出錯(cuò): $w1->getName()產(chǎn)生了一個(gè)錯(cuò)誤. 但子類(lèi)Thing中的getName方法可以調(diào)用這個(gè)protected方法.當(dāng)然對(duì)于證明Widget::getName方法是protected,這個(gè)例子顯得過(guò)于簡(jiǎn)單. 在實(shí)際情況下,使用protected方法要依賴(lài)于對(duì)對(duì)象的內(nèi)部結(jié)構(gòu)的理解. Listing 6.9 Protected members <?php class Widget { private $name; private $price; private $id; public function __construct($name, $price) { $this->name = $name; $this->price = floatval($price); $this->id = uniqid(); } //checks if two widgets are the same public function equals($widget) { return(($this->name == $widget->name)AND ($this->price == $widget->price)); } protected function getName() { return($this->name); } } class Thing extends Widget { private $color; public function setColor($color) { $this->color = $color; } public function getColor() { return($this->color); } public function getName() { return(parent::getName()); } } $w1 = new Widget('Cog', 5.00); $w2 = new Thing('Cog', 5.00); $w2->setColor('Yellow'); //TRUE (still!) 結(jié)果仍然為真 if($w1->equals($w2)) { print("w1 and w2 are the same<br>\n"); } //print Cog 輸出 Cog print($w2->getName()); ?> 一個(gè)子類(lèi)可能改變通過(guò)覆寫(xiě)父類(lèi)方法來(lái)改變方法的訪問(wèn)方式,盡管如此,仍然有一些限制. 如果你覆寫(xiě)了一個(gè)public類(lèi)成員,他子類(lèi)中必須保持public. 如果你覆寫(xiě)了一個(gè)protected成員,它可保持protected或變成public.Private成員仍然只在當(dāng)前類(lèi)中可見(jiàn). 聲明一個(gè)與父類(lèi)的private成員同名的成員將簡(jiǎn)單地在當(dāng)前類(lèi)中建立一個(gè)與原來(lái)不同的成員. 因此,在技術(shù)上你不能覆寫(xiě)一個(gè)private成員. Final關(guān)鍵字是限制訪問(wèn)成員方法的另一個(gè)方法. 子類(lèi)不能覆寫(xiě)父類(lèi)中標(biāo)識(shí)為final的方法. Final關(guān)鍵字不能用于屬性. //haohappy注:PHP5的面向?qū)ο竽P腿匀徊粔蛲晟?如final不像Java中那樣對(duì)Data,Method甚至Class都可以用. |
溫馨提示:喜歡本站的話(huà),請(qǐng)收藏一下本站!