摘要:不同點(diǎn)語法上的不同,對(duì)接口的使用是通過關(guān)鍵字,定義是使用關(guān)鍵字對(duì)抽象類的使用是通過關(guān)鍵字當(dāng)然接口也可以通過關(guān)鍵字繼承,定義是使用關(guān)鍵字。接口只有常量和方法,抽象類則包含普通類中的一切機(jī)構(gòu)。接口中的方法都必須是類型的,而抽象類則不受限制。
不同點(diǎn)
語法上的不同,對(duì)接口的使用是通過關(guān)鍵字implements,定義是使用關(guān)鍵字interface;對(duì)抽象類的使用是通過關(guān)鍵字extends(當(dāng)然接口也可以通過關(guān)鍵字extends繼承),定義是使用關(guān)鍵字abstract class。
接口只有常量和方法,抽象類則包含普通類中的一切機(jī)構(gòu)。
接口中的方法都必須是public類型的,而抽象類則不受限制。
一個(gè)類可以同時(shí)實(shí)現(xiàn)多個(gè)接口,但一個(gè)類只能繼承一個(gè)抽象類。
抽象類中可以定義普通的帶有方法體的方法,而接口不行
相同點(diǎn)接口中的方法和抽象類中的抽象方法都不能有方法體,并且在其子類中都必須被實(shí)現(xiàn)
都可以被繼承但不能被實(shí)例化
適用場景如果要?jiǎng)?chuàng)建一個(gè)模型,這個(gè)模型將由一些緊密相關(guān)的對(duì)象采用,就可以使用抽象類。如果要?jiǎng)?chuàng)建將由一些不相關(guān)對(duì)象采用的功能,就使用接口。
如果必須從多個(gè)來源繼承行為,就使用接口。
如果知道所有類都會(huì)共享一個(gè)公共的行為實(shí)現(xiàn),就使用抽象類,并在其中實(shí)現(xiàn)該行為。
以下代碼摘抄自燕十八公益課堂
/* 春秋戰(zhàn)國時(shí)期,燕零七 飛行器專家,能工巧匠. 他寫了一份圖紙---飛行器制造術(shù) 飛行器秘制圖譜 1: 要有一個(gè)有力的發(fā)動(dòng)機(jī),噴氣式. 2: 要有一個(gè)平衡舵,掌握平衡 他的孫子問: 發(fā)動(dòng)機(jī)怎么造呢? 燕零七眼望夕陽: 我是造不出來,但我相信后代有人造出來 燕零七的構(gòu)想在當(dāng)時(shí)的科技造不出來,即這個(gè)類只能在圖紙化,無法實(shí)例化. ***/ // 此時(shí)這個(gè)類沒有具體的方法去實(shí)現(xiàn),還太抽象. // 因此我們把他做成一個(gè)抽象類 abstract class FlyIdea { // 大力引擎,當(dāng)時(shí)也沒法做,這個(gè)方法也實(shí)現(xiàn)不了,因此方法也是抽象的 public abstract function engine(); // 平衡舵 public abstract function blance(); /* 注意:抽象方法 不能有方法體 下面這樣寫是錯(cuò)誤的 public abstract function blance() { } Fatal error: Abstract function FlyIdea::engine() cannot contain body */ } /* 抽象類不能 new 來實(shí)例化 下面這行是錯(cuò)誤的 $kongke = new FlyIdea(); Cannot instantiate abstract class FlyIdea */ // 到了明朝,萬戶用火箭解決了發(fā)動(dòng)機(jī)的問題 abstract class Rocket extends FlyIdea { // 萬戶把engine方法,給實(shí)現(xiàn)了,不再抽象了 public function engine() { echo "點(diǎn)燃火藥,失去平衡,嘭!
"; } // 但是萬戶實(shí)現(xiàn)不了平衡舵,因此平衡舵對(duì)于Rocket類來說,還是抽象的,類也是抽象的 // 此處由于繼承父類的也是抽象類,所以可以不必完成抽象類中的所有抽象方法; } /* 到了現(xiàn)代,燕十八親自制作飛行器 這個(gè)Fly類中,所以抽象方法,都已經(jīng)實(shí)現(xiàn)了,不再是夢想. */ //到了這個(gè)類就必須要完成所有的抽象方法; class Fly extends Rocket{ public function engine() { echo "有力一扔
"; } public function blance() { echo "兩個(gè)紙翼保持平衡~~~"; } public function start() { $this->engine(); for($i=0;$i<10;$i++) { $this->blance(); echo "平穩(wěn)飛行
"; } } } $apache = new Fly(); $apache->start();
/* 類: 是某一類事物的抽象,是某類對(duì)象的藍(lán)圖. 比如: 女媧造人時(shí),腦子中關(guān)于人的形象 就是人類 class Human 如果,女媧決定造人時(shí), 同時(shí),形象又沒最終定稿時(shí), 她腦子有哪些支離破碎的形象呢? 她可能會(huì)這么思考: 動(dòng)物: 吃飯 猴子: 奔跑 猴子: 哭 自己: 思考 小鳥: 飛 我造一種生物,命名為人,應(yīng)該有如下功能 eat() run(); cry(); think(); 類如果是一種事物/動(dòng)物的抽象 那么 接口,則是事物/動(dòng)物的功能的抽象, 即,再把他們的功能各拆成小塊 自由組合成新的特種 */ ; interface animal { const NAME = "zxg"; //不能定義屬性,但可以定義常量; public function eat(); } interface monkey { public function run(); public function cry(); } interface wisdom { public function think(); } interface bird { public function fly(); } /* 如上,我們把每個(gè)類中的這種實(shí)現(xiàn)的功能拆出來 分析: 如果有一種新生物,實(shí)現(xiàn)了eat() + run() +cry() + think() ,這種智慧生物,可以叫做人. class Human implements animal,monkey,wisdom { } Human類必須要包含animal,monkey,wisdom接口里面的方法,缺一不可,否則就會(huì)報(bào)錯(cuò) Class Human contains 4 abstract methods */ class Human implements animal, monkey, wisdom, bird { //這里的接口數(shù)量可以隨意增加;增 加了以后本類里面的方法必須要有新增加的接口里面的方法 public function eat() { echo "吃東西方法"; } public function run() { echo self::NAME; //可以通過self來訪問任意一個(gè)接口所定義的常量; echo "行走的方法"; } public function cry() { echo "哭的方法"; } public function think() { echo animal::NAME; //也可以通過 接口名 echo "思考的方法"; } public function smile() { echo "這是新增加的微笑方法"; } public function fly() { echo "這是新增加的接口bird里面的fly方法"; } } $obj = new Human(); $obj -> think(); /*** ====筆記部分==== 面向?qū)ο蟮囊粋€(gè)觀點(diǎn): 做的越多,越容易犯錯(cuò) 抽象類{就定義類模板}--具體子類實(shí)現(xiàn){china,japan,english} 接口: ***/ // 抽象的數(shù)據(jù)庫類 /* 創(chuàng)業(yè)做網(wǎng)站 到底用什么數(shù)據(jù)庫? mysql, oracle,sqlserver,postgresql? 這樣:先開發(fā)網(wǎng)站,運(yùn)行再說. 先弄個(gè)mysql開發(fā)著,正式上線了再換數(shù)據(jù)庫也不遲 引來問題: 換數(shù)據(jù)庫,會(huì)不會(huì)以前的代碼又得重寫? 答:不必,用抽象類 開發(fā)者,開發(fā)時(shí),就以db抽象類來開發(fā). */ abstract class db { public abstract function connect($h,$u,$p); public abstract function query($sql); public abstract function close(); } /* // 下面這個(gè)代碼有誤 // 因?yàn)樽宇悓?shí)現(xiàn)時(shí), connect和抽象類的connect參數(shù)不一致 class mysql extends db { public function connect($h,$h) { return true; } public function query($sql,$conn) { } public function close() { } } */ /* 下面這個(gè)mysql類,嚴(yán)格實(shí)現(xiàn)了db抽象類 試想: 不管上線時(shí),真正用什么數(shù)據(jù)庫 我只需要再寫一份如下類 class oracle extends db { } class mssql extends db { } class postsql extends db { } 業(yè)務(wù)邏輯層不用改? 為什么不用改? 因?yàn)槎紝?shí)現(xiàn)的db抽象類. 我開發(fā)時(shí),調(diào)用方法不清楚的地方,我就可以參考db抽象類. 反正子類都是嚴(yán)格實(shí)現(xiàn)的抽象類. */ class mysql extends db { public function connect($h,$h,$u) { return true; } public function query($sql) { } public function close() { } } /* 接口 就更加抽象了 比如一個(gè)社交網(wǎng)站, 關(guān)于用戶的處理是核心應(yīng)用. 登陸 退出 寫信 看信 招呼 更換心情 吃飯 罵人 搗亂 示愛 撩騷 這么多的方法,都是用戶的方法, 自然可以寫一個(gè)user類,全包裝起來 但是,分析用戶一次性使不了這么方法 用戶信息類:{登陸,寫信,看信,招呼,更換心情,退出} 用戶娛樂類:{登陸,罵人,搗亂,示愛,撩騷,退出} 開發(fā)網(wǎng)站前,分析出來這么多方法, 但是,不能都裝在一個(gè)類里, 分成了2個(gè)類,甚至更多. 作用應(yīng)用邏輯的開發(fā),這么多的類,這么多的方法,都暈了. */ interface UserBase { public function login($u,$p); public function logout(); } interface UserMsg { public function wirteMsg($to,$title,$content); public function readMsg($from,$title); } interface UserFun { public function spit($to); public function showLove($to); } /* 作為調(diào)用者, 我不需要了解你的用戶信息類,用戶娛樂類, 我就可以知道如何調(diào)用這兩個(gè)類 因?yàn)? 這兩個(gè)類 都要實(shí)現(xiàn) 上述接口. 通過這個(gè)接口,就可以規(guī)范開發(fā). */ /* 下面這個(gè)類,和接口聲明的參數(shù)不一樣,就報(bào)錯(cuò), 這樣,接口強(qiáng)制統(tǒng)一了類的功能 不管你有幾個(gè)類,一個(gè)類中有幾個(gè)方法 我只知道,方法都是實(shí)現(xiàn)的接口的方法. */ class User implements UserBase { public function login($u) { } }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/28443.html
摘要:不過怎么來說工廠方法模式是簡單工廠模式的升級(jí)版。其次,工廠模式是一種典型的解耦模式,迪米特法則在工廠模式中表現(xiàn)的尤為明顯。 工廠模式想必大家在開發(fā)過程中會(huì)經(jīng)常用到,顧名思義其就是作為一個(gè)工廠用來生產(chǎn)產(chǎn)品的,下面來簡單介紹幾種常見的工廠模式。 0x01 簡單工廠模式 1、類圖結(jié)構(gòu)showImg(/img/bVFf1t?w=531&h=278); 2、角色分類 工廠類:其內(nèi)部具有一點(diǎn)的判...
摘要:但是從客觀上而言,業(yè)務(wù)代碼本身由于包含了業(yè)務(wù)領(lǐng)域的知識(shí),復(fù)雜可以說是先天的屬性。原來業(yè)務(wù)代碼也可以這么簡潔而優(yōu)雅。因?yàn)榇藘?nèi)部業(yè)務(wù)框架做的事情很多,篇幅有限,這里僅對(duì)最具借鑒意義的領(lǐng)域建模思考作介紹。其實(shí)也是很典型的一種業(yè)務(wù)代碼編寫方式。 本文主要作為筆者閱讀Eric Evans的《Domain-Driven Design領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)》一書,同時(shí)拜讀了我司大神針對(duì)業(yè)務(wù)代碼封裝的一套業(yè)務(wù)框...
摘要:抽象工廠模式是為了處理對(duì)象具有等級(jí)結(jié)構(gòu)以及對(duì)象族的問題。單例設(shè)計(jì)模式單例模式確保某一個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例,這個(gè)類成為單例類。 導(dǎo)語:設(shè)計(jì)模式是無數(shù)碼農(nóng)前人在實(shí)際的生產(chǎn)項(xiàng)目中經(jīng)過不斷的踩坑、爬坑、修坑的經(jīng)歷總結(jié)出來的經(jīng)驗(yàn)教訓(xùn),經(jīng)過抽象之后表達(dá)成的概念。能夠幫助后來的設(shè)計(jì)者避免重復(fù)同樣的錯(cuò)誤或者彎路。我也抽空整理了一下設(shè)計(jì)模式,用自己的話總結(jié)了一下,自認(rèn)...
摘要:本文重點(diǎn)不要試圖在內(nèi)置類型的子類中重寫方法,可以繼承的可拓展類尋求變通掌握多重繼承中的和了解處理多重繼承的一些建議。子類化的代碼如下輸出小結(jié)上述問題只發(fā)生在語言實(shí)現(xiàn)的內(nèi)置類型子類化情況中,而且只影響直接繼承內(nèi)置類型的自定義類。 導(dǎo)語:本文章記錄了本人在學(xué)習(xí)Python基礎(chǔ)之面向?qū)ο笃闹攸c(diǎn)知識(shí)及個(gè)人心得,打算入門Python的朋友們可以來一起學(xué)習(xí)并交流。 本文重點(diǎn): 1、不要試圖在內(nèi)置...
閱讀 1459·2021-11-22 13:52
閱讀 1281·2021-09-29 09:34
閱讀 2690·2021-09-09 11:40
閱讀 3031·2019-08-30 15:54
閱讀 1255·2019-08-30 15:53
閱讀 971·2019-08-30 11:01
閱讀 1354·2019-08-29 17:22
閱讀 1943·2019-08-26 10:57