摘要:而哈士奇區(qū)別于普通狗,又有新的特征逗比,愛(ài)搗亂為了保證類(lèi)之間的松綁定,通常會(huì)繼承抽象類(lèi),而且是淺繼承只有一層子類(lèi)。如果知道所有類(lèi)都會(huì)共享一個(gè)公共的行為實(shí)現(xiàn),就使用抽象類(lèi),并在其中實(shí)現(xiàn)該行為。
為什么使用OOP
OOP是一個(gè)模塊化的過(guò)程,目的是為了把復(fù)雜問(wèn)題簡(jiǎn)單化,一個(gè)模塊解決一個(gè)復(fù)雜問(wèn)題的某一個(gè)方面,即一個(gè)類(lèi)應(yīng)當(dāng)只有一個(gè)職責(zé)
OOP區(qū)別于順序式編程與過(guò)程式編程,在于:
1.順序編程:用于處理最簡(jiǎn)單的問(wèn)題 2.過(guò)程編程:將代碼分為模塊以便在程序中重用,程序猿輸為一個(gè)函數(shù) 輸入不同實(shí)參就能利用不同具體值使用函數(shù) 3.OOP:形同過(guò)程編程,長(zhǎng)處在于能處理自己的數(shù)據(jù)結(jié)構(gòu),更方便地處理 獨(dú)立但相互關(guān)聯(lián)的類(lèi)
從外部源啟動(dòng)PHP類(lèi),往往由其它模塊調(diào)動(dòng),不會(huì)自啟動(dòng),舉個(gè)反例:
OOP基本概念 抽象(abstract)用于指示一個(gè)對(duì)象的基本特征,是處理復(fù)雜性的具體方法。
我們會(huì)對(duì)現(xiàn)實(shí)中的相似性分組,對(duì)具體的相似性抽象。
舉個(gè)例子:我們一般不會(huì)叫自己的愛(ài)寵哈士奇為"我的蠢萌蠢萌的、搖著尾巴的、愛(ài)搗亂的名叫Jeff的哈士奇",而往往會(huì)直接說(shuō):"我的狗!"
抽象類(lèi)不能實(shí)例化,只能由具體類(lèi)(可以實(shí)例化的類(lèi),非抽象類(lèi))繼承抽象類(lèi)的接口以及所有具體屬性
所有類(lèi)都是對(duì)數(shù)據(jù)的一組操作的抽象
基本語(yǔ)法:
接口(interface)不能像抽象類(lèi)那樣在接口中包含具體方法或變量,除非是具有抽象性的接口,可以包含具體常量
接口的核心部分由類(lèi)中操作(函數(shù))定義的所有簽名組成。簽名包括一個(gè)操作的操作名和參數(shù),一個(gè)接口表示的就是所有簽名的集合。例如以下代碼,簽名由trick()和形參$whatever組成
public function trick($whatever){ echo "signature"; }
如果要實(shí)現(xiàn)接口(implements),就要保證實(shí)現(xiàn)接口中的所有方法,在此基礎(chǔ)上可以再繼續(xù)添加額外的方法
"; } public function sendInfo(){ return $Info; } public function calculate($first,$second){ $calculate = $first * $second; return $calculate; } /******** 除此之外可以增加其他類(lèi) ********/ public function useMethods(){ $this->getInfo("習(xí)近平會(huì)見(jiàn)馬英九"); echo $this->sendInfo("恒大戰(zhàn)平阿赫利") . "
"; echo "Salary : $" . $this->calculate(20,15) ; } $worker = new ImplementAlpha; $worker->useMethods(); //前面提到不要自啟動(dòng),這里為了方便就直接自啟動(dòng)實(shí)例化類(lèi) //不過(guò)可以看到,在實(shí)現(xiàn)類(lèi)中,方法都是經(jīng)過(guò)useMethods的方法調(diào)用的 //在后面章你會(huì)看到很多例子都是這樣實(shí)現(xiàn)的,而往往不會(huì)直接調(diào)用 } ?>
OOP和設(shè)計(jì)模式有很多重要的結(jié)構(gòu)要素,其中之一就是指定數(shù)據(jù)類(lèi)型為接口而不是一個(gè)具體實(shí)現(xiàn),對(duì)數(shù)據(jù)的引用要通過(guò)父類(lèi)完成。如下所示:
//useProduct.php //兩個(gè)實(shí)現(xiàn)include進(jìn)來(lái),此處省略代碼 class useProduct{ public function __construct(){ $apple = new FruitStore(); $book = new BookStore(); $this->doInterface($apple); $this->doInterface($book); //實(shí)例化類(lèi)在一個(gè)方法中,調(diào)用類(lèi)的方法又在另一個(gè)方法中,降低了耦合度 } function doInterface(IProduct $product){ echo $product->apples(); echo $product->books(); } } $worker = new useProduct(); ?>
這就是強(qiáng)制數(shù)據(jù)類(lèi)型,其中使用的對(duì)象(類(lèi))必然有給定的接口,如果把一個(gè)接口 (一個(gè)對(duì)象類(lèi)或者接口) 作為代碼提示,綁定會(huì)更寬松)它會(huì)綁定到接口而不是綁定到一個(gè)特定的實(shí)現(xiàn),如上面的doInterface(IProduct $product)
封裝(Encapsulation)封裝是畫(huà)份一個(gè)抽象的諸多元素的過(guò)程,這些元素構(gòu)成該抽象的結(jié)構(gòu)和行為,封裝的作用就是將抽象的契約接口與其實(shí)現(xiàn)分離
通過(guò)3種類(lèi)型的可見(jiàn)性保護(hù)封裝(private/protected/public)。但是一個(gè)類(lèi)還是要有可見(jiàn)方法訪問(wèn)封裝,比如__consruct構(gòu)造函數(shù),默認(rèn)為公共的
為了保持封裝而又提供可訪問(wèn)性,OOP建議使用getter()和setter()方法,但是不能濫用,否則會(huì)破壞封裝
setter(200); $got = $this->getter(); echo $got; } private function getter(){ return $this->data; } private function setter($setValue){ $this->data = $setValue; } } $worker = new GetSet(); ?>繼承(extends)
假設(shè)我有一只哈士奇(我們稱(chēng)之為子類(lèi)),那么它繼承了狗(父類(lèi))的屬性,比如四只腳,看到的世界都是通過(guò)#404040層過(guò)濾的。而哈士奇區(qū)別于普通狗,又有新的特征:逗比,愛(ài)搗亂
為了保證類(lèi)之間的松綁定,通常會(huì)繼承抽象類(lèi),而且是淺繼承(只有一層子類(lèi))。深繼承的話(huà),一旦對(duì)父類(lèi)進(jìn)行簡(jiǎn)單修改,子類(lèi)會(huì)帶來(lái)嚴(yán)重的破壞
$pet = $petChar; } } ?>
fourlegs() . "多態(tài)(polymorphism)
"; echo $this->character("They are crazy!") . "
"; echo $this->naughty() . "
"; } private function naughty(){ return "Haski dogs are naughty"; } } ?>
多態(tài)的真正價(jià)值在于可以調(diào)用有相同接口的對(duì)象來(lái)完成不同的工作。一個(gè)大型項(xiàng)目中,增加和修改會(huì)對(duì)程序帶來(lái)巨大影響,除非有一個(gè)公共的接口(父類(lèi)或接口),例如:
從上面的例子看出,Jet和Car類(lèi)對(duì)接口的實(shí)現(xiàn)有很大不同。但是基于這樣一個(gè)公共接口,在一個(gè)給定的程序結(jié)構(gòu)中做出修改或者增補(bǔ)時(shí),可以放心地請(qǐng)求或使用接口方法,而不必?fù)?dān)心程序會(huì)崩潰
抽象還是接口(引用于CSDN-PHP的抽象類(lèi)、接口的區(qū)別)
如果要?jiǎng)?chuàng)建一個(gè)模型,這個(gè)模型將由一些緊密相關(guān)的對(duì)象采用,就可以使用抽象類(lèi)。如果要?jiǎng)?chuàng)建將由一些不相關(guān)對(duì)象采用的功能,就使用接口。
如果必須從多個(gè)來(lái)源繼承行為,就使用接口。
如果知道所有類(lèi)都會(huì)共享一個(gè)公共的行為實(shí)現(xiàn),就使用抽象類(lèi),并在其中實(shí)現(xiàn)該行為。
PS:該篇引用于《Learning PHP設(shè)計(jì)模式》第1、2章節(jié)
Chap2 預(yù)告 :設(shè)計(jì)模式與UML算法處理操作速度,設(shè)計(jì)模式解決開(kāi)發(fā)速度
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/21209.html
摘要:工廠模式優(yōu)點(diǎn)集中實(shí)例化,可以傳參等缺點(diǎn)分不清屬于哪個(gè)對(duì)象我們先來(lái)談?wù)剝?yōu)點(diǎn),看例子集中實(shí)例化返回實(shí)例化對(duì)象返回返回不難看出,工廠模式比上面的例子減少了很多代碼。 ECMAscript開(kāi)發(fā)的兩種模式:1.過(guò)程化 2.OOP(面向?qū)ο? 面向?qū)ο蟮恼Z(yǔ)言有一個(gè)標(biāo)志,那就是類(lèi)的概念,而通過(guò)類(lèi)可以創(chuàng)建任意多個(gè)具有相同屬性的方法的對(duì)象。但是ECMAscript中沒(méi)有類(lèi)的概念! 又談作用域 首先...
摘要:構(gòu)造函數(shù)上一章我們講了工廠模式,它的缺點(diǎn)就是無(wú)法識(shí)別到底哪個(gè)屬于哪個(gè)的問(wèn)題。我們可以用構(gòu)造函數(shù)來(lái)解決這個(gè)識(shí)別問(wèn)題。來(lái)比較構(gòu)造函數(shù)內(nèi)的值就可以看出到底是什么類(lèi)型。 構(gòu)造函數(shù) 上一章我們講了工廠模式,它的缺點(diǎn)就是無(wú)法識(shí)別到底哪個(gè)屬于哪個(gè)的問(wèn)題。我們可以用構(gòu)造函數(shù)來(lái)解決這個(gè)識(shí)別問(wèn)題。 //構(gòu)造函數(shù) function Create(a,b) { this.a =a; this...
摘要:上一章我們談了構(gòu)造函數(shù),他的唯一特點(diǎn)就是比較了地址不相同,因?yàn)榇蠹抑酪妙?lèi)型是比較的引用。也就是說(shuō)不用在構(gòu)造函數(shù)中定義對(duì)象實(shí)例,而是直接將這些添加到原型當(dāng)中。如果構(gòu)造函數(shù)實(shí)例里面沒(méi)有,就去原型里面查找,如果有就立即返回。 上一章我們談了構(gòu)造函數(shù),他的唯一特點(diǎn)就是比較了地址不相同,因?yàn)榇蠹抑酪妙?lèi)型是比較的引用。我們來(lái)談?wù)勗汀?原型 我們每創(chuàng)建一個(gè)函數(shù)都有一個(gè)原型(prototyp...
摘要:原型設(shè)計(jì)模式中,原型設(shè)計(jì)模式的關(guān)鍵是要了解如何使用內(nèi)置函數(shù)抽象原型角色聲明一個(gè)克隆自身的接口具體原型角色實(shí)現(xiàn)一個(gè)克隆自身的操作原型設(shè)計(jì)模式的目的通過(guò)克隆以減少實(shí)例化對(duì)象的開(kāi)銷(xiāo),與其實(shí)例化新對(duì)象,完全可以使用一個(gè)已有實(shí)例的克隆注意類(lèi)是原型設(shè)計(jì) 原型設(shè)計(jì)模式 Notice: PHP中,原型設(shè)計(jì)模式的關(guān)鍵是要了解如何使用內(nèi)置函數(shù)__clone() 抽象原型角色(Prototype):聲明一...
摘要:設(shè)計(jì)模式設(shè)計(jì)模式基本原則設(shè)計(jì)原則按接口而不是按實(shí)現(xiàn)來(lái)編程按接口而不是按實(shí)現(xiàn)編程是指,要將變量設(shè)置為一個(gè)抽象類(lèi)或接口數(shù)據(jù)類(lèi)型的實(shí)例,而不是一個(gè)具體實(shí)現(xiàn)的實(shí)例。例如父類(lèi)的一個(gè)改變會(huì)逐級(jí)向下傳遞給子類(lèi)實(shí)現(xiàn),這可能會(huì)影響子類(lèi)使用的某個(gè)算法。 設(shè)計(jì)模式 設(shè)計(jì)模式基本原則 設(shè)計(jì)原則 ① : 按接口而不是按實(shí)現(xiàn)來(lái)編程 按接口而不是按實(shí)現(xiàn)編程是指,要將變量設(shè)置為一個(gè)抽象類(lèi)或接口數(shù)據(jù)類(lèi)型的實(shí)例,而不是一...
閱讀 2431·2021-09-22 15:41
閱讀 1448·2021-08-19 10:54
閱讀 1755·2019-08-23 15:11
閱讀 3402·2019-08-23 10:23
閱讀 1428·2019-08-22 16:28
閱讀 799·2019-08-22 15:11
閱讀 739·2019-08-22 14:53
閱讀 710·2019-08-22 13:49