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