您好,登錄后才能下訂單哦!
這篇文章主要介紹“面向對象3個特性7個原則6種關系是什么”,在日常操作中,相信很多人在面向對象3個特性7個原則6種關系是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”面向對象3個特性7個原則6種關系是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
依照PHP的語法為主,不同的編程語言,有不同的方式,但大體上都是一樣的。
面向對象的思想在于理解和使用。
文章所說的接口,都是編程語言語法的接口(interface),而不是前端調用的接口(api)。
軟件,是為了解決人類發展的問題,方便人類的工具,如果一個計算機,或者一個軟件只會算數,那么遇見匯率換算怎么辦?是不是可以說計算機本身如果沒有太多的固有功能,就無法完成某些事。而現在的軟件,可以幫助人們購物,相親,娛樂。這么復雜的功能來說,如果軟件思想沒有發展出更高級的思想,它是無法為人類服務的,所以為了可維護性更強,具有更強的功能,必須在計算機軟件編程本身上提出一些更高級的概念,用于實現比算加減乘除更復雜的功能,多樣化的規則成了一套實用高效的規范,那么就是下文看到的各種計算機名詞。
“面向”此處可以理解為按照什么思路去編程。
對象是一種依照事物為中心的編程思想,萬物皆對象,由實體引發事件,對象是真實存在的,對象也可以理解為是把數據結構和處理它們的方法,組成對象。達到了軟件工程的三個目標,重用性靈活性和擴展性。 重用性: 一個類里面的方法可以多次使用。 靈活性: 可以表現為多態,可重復調動等特點,自由度很高,條條大路通羅馬。 擴展性: 多態,繼承都有這個特性,可便于多樣化擴展,進行抽離,降低耦合。
可以理解為對象的抽象化概念,分離出相同的特點,并加以歸類。 把相同行為的對象歸納為類,一個人是一個對象,但是多個人可以歸納為一個人類,人類指的不是某一個,而是一個虛擬的實體概念。為什么有人這個類?因為人有雙手,會用火,有文明,學習能力強等因素,如果想要從人類上說某個人,那就是舉一個實例,也就是實例化。
屬性可以理解數據,數據是信息和表現形式的載體。依照人為例,人有鼻子有眼,這個就是人的屬性。可以用 有 來形容。
方法可以理解為函數。方法是控制數據的管家。依照人為例,人會說話,會吃飯,這就人的方法。可以用 做 來形容。
可以理解為一個類中需要指定它需要做什么,但是不需要去做,起到一個規范示例的作用,就是一個標準,需要其它的類去實現它。例如定義了usb接口的尺寸,大小,數據線連接方法,可以類比成一個接口規范,全世界的usb接口都通用,無論是U盤,充電器線,鼠標,鍵盤。這些實例都可以根據這個約束規范,去制造東西。接口的使用需要用 實現 兩個字形容。
封裝: 通過封裝隱藏類的內部方法或者數據,只允許訪問可以訪問的資源,保證安全性。擬人化來說,就是姓名是公開的,銀行密碼的信息是個人的,PHP可用public protected private去修飾。
繼承: 繼承使類得到泛化,兒子繼承爸爸,可以獲得父級或者父級往上的非私有屬性,或者方法,使用extends關鍵字。
多態: 可實現基于對象類型的動態分派,不同的人做同一件事,得到不同的結果。相親這件事:女生遇到流氓會說滾,遇到帥哥會說么么噠。
單一原則: 一個類就做一件事,職責被完整的封裝在一個類中。不會引起混亂,提高重用性,低耦合的設計可以降低軟件開發后期的維護。
開閉原則: 對修改關閉,對擴展開放。因為需求變更,運行環境升級等原因需要改代碼,如果沒有出現bug,那么不推薦改原來的代碼,可以在原基礎上進行擴充。既增加了擴展性,又保證原來的邏輯不出問題。所謂的“祖傳代碼,勿動”,也就是這么一回事。
里氏代換原則: 通俗講:所有能用到老爸的地方,兒子也能使用。軟件中能夠使用的基類對象,那么就要做到任何地方能使用子類對象而不受影響。也就是子類能夠替換程序中父類出現的任何地方,并保證邏輯不變和正確,這里面暗含著不推薦重寫父類的意思。正是因為有了這個標準,才能防止父級一旦修改,就會殃及子級發生故障的情況。這個原則實現了開閉原則的形式,子類就相當于擴展。實質上這個原則是要告訴我們,繼承需要注意的問題和遵循的原則。但繼承是增加了父子類的耦合關系,為了解決依賴,可以適當通過聚合,組合,依賴等來解決。
依賴倒轉原則: 就是面向接口編程。把共用的可復用的方法放置到抽象類,抽象思維編程,或者接口當中,依照抽象耦合的方式是原則的關鍵,目的是降低耦合。高層模塊(舉個例子:高層模塊就是框架底層的代碼,依照PHP為例,框架底層的代碼,好多都是抽象類或者接口)不依賴底層模塊,二者依賴于抽象。抽象不應該依賴細節,細節應該依賴抽象,也就是做到細節和非細節的分離,相對于細節的多變性,抽象的東西要穩定的多。抽象為基礎搭建的架構比細節為基礎的架構要穩定的多。舉個例子,功能的大體實現可以使用抽象類,但是細節,可以使用具體的類去實現。這里所謂的抽象,是用于定制規范和整體架構。 舉個栗子:
//這段代碼適用于發送郵件,但是要增加發送微信的功能,是不是就顯得麻煩了?這里不要抬杠說把“Email $email”去掉,如果項目中大量的業務邏輯已經這樣寫了,把“Email $email”去掉,可能要出問題的。 <?php class Email { public function send() { return '發送電子郵件'; } } class WeChat { public function send() { return '發送微信消息'; } } class Person { public function receive(Email $email) { return $email->send(); } } $person = new Person(); echo $person->receive(new Email());
再看看 優化的結果,所謂的抽象就是發送信息,細節就是發送信息的方式和內容,抽象和細節做了分離,降低耦合。
<?php //接口定義大致的方法,大方向 interface SendMsg { public function send(); } //具體的類去實現細節 class Email implements SendMsg { public function send() { return '發送電子郵件'; } } //具體的類去實現細節 class WeChat implements SendMsg { public function send() { return '發送微信消息'; } } //此處降低耦合 class Person { public function receive(SendMsg $send_msg) { return $send_msg->send(); } } $person = new Person(); //靈活調用 echo $person->receive(new Email()); echo $person->receive(new WeChat());
接口隔離原則: 還是為了降低耦合,減少接口類中臃腫的代碼段,一個類對另一個類的依賴應該建立在最小的接口上,通俗的講就是需要什么就提供什么,不需要的就不要提供。比如接口類Test一共有func1,func2,func3,func4,func5 5個方法,A類依賴Test接口 func1,func2,func3三個方法,B類依賴Test接口 func1,func2,func4三個方法。這樣的接口func5就沒有用上,應該做接口拆分,拆分成A類和B類依賴的接口僅僅夠用程度的接口即可,并且增加安全性,這里的拆,就是具有隔離不需要的代碼的作用。
<?php //接口定義了5個方法 interface TestInterface { public function func1(); public function func2(); public function func3(); public function func4(); public function func5(); } //A類依賴了接口中123三個方法,但func4 和 func5用不上 class A implements TestInterface { public function func1() { return '實現了TestInterface接口的func1方法';} public function func2() { return '實現了TestInterface接口的func2方法';} public function func3() { return '實現了TestInterface接口的func3方法';} public function func4() { return '這兩個方法用不上,但是由于PHP語法問題,需要去實現';} public function func5() { return '這兩個方法用不上,但是由于PHP語法問題,需要去實現';} } //A類依賴了接口中124三個方法,但func3 和 func5用不上 class B implements TestInterface { public function func1() { return '實現了TestInterface接口的func1方法';} public function func2() { return '實現了TestInterface接口的func2方法';} public function func3() { return '這兩個方法用不上,但是由于PHP語法問題,需要去實現';} public function func4() { return '實現了TestInterface接口的func4方法';} public function func5() { return '這兩個方法用不上,但是由于PHP語法問題,需要去實現';} }
再看不臃腫的代碼:
<?php interface TestInterface_A { public function func1(); public function func2(); public function func3(); } interface TestInterface_B { public function func1(); public function func2(); public function func4(); } //A類實現了接口中123三個方法,無需依賴額外的方法 class A implements TestInterface_A { public function func1() { return '實現了TestInterface接口的func1方法';} public function func2() { return '實現了TestInterface接口的func2方法';} public function func3() { return '實現了TestInterface接口的func3方法';} } //A類實現了接口中124三個方法,無需依賴額外的方法 class B implements TestInterface_B { public function func1() { return '實現了TestInterface接口的func1方法';} public function func2() { return '實現了TestInterface接口的func2方法';} public function func4() { return '實現了TestInterface接口的func4方法';} }
合成復用原則: 多用組合(has-a),少用繼承(is-a),可以降低類與類之間的耦合程度。遇見額外增加的功能,需要擴展,通過關聯,而不是繼承。因為使用繼承,后期改父級代碼可能會株連子級,引起錯誤。 繼承復用又稱之為白箱復用,組合聚合使用稱之為黑箱復用。
迪米特法則/最少知道原則 一個軟件實體盡可能少的與其它實體發生作用,限制了編程中通信的寬度和深度,不管依賴的類有多么的復雜,都盡量把邏輯封裝到類內部,除了對外提供public的方法,不對外泄露任何無關信息。只和朋友通信,朋友通常是當前類、當前對象、成員屬性,成員方法參數,成員方法返回值這些。其余的都是陌生人,不可直接調用。 法則又可以分為狹義法則和廣義法則。狹義的說法是:類A和類B發生關聯,類B和類C發生關聯,那么類A和類C是不能直接訪問的,需要通過B。優點是降低耦合,缺點是需要大量的局部化設計,讓類A可以訪問類C,造成模塊間使用效率降低。廣義的說法是:盡量創建松耦合的類,控制信息的過載,類之間的耦合度越低,越有利于復用,但是需要更高的抽象分離思想。
并由此出現了23種設計模式,設計模式用于解決經典場景下的經典問題而出來的通用實用規范。但23種有些并不適用于PHP語言,一旦強制使用,就缺失了弱類型語言的優點。
面向過程是依事件為中心,分析出解決問題的步驟,將代碼分成若干個過程/函數,一步步實現,其中,函數或過程是最小的模塊封裝單位,然后調用這些函數,可以稱之為方法。所謂的通俗講封裝就是把一堆代碼括起來。 面向對象也是基于面向過程的思想,面向對象實現,也必定有相應的過程,所以有很多相同點。
過程: 無返回值。 函數: 有返回值。
繼承: 兒子繼承爸爸,子類可以使用父類的任何非私有成員方法或成員屬性,且可以隨意擴展,并且可以通過子類重寫放寬對資源的訪問修飾,且可以重寫父類非私有的的方法或成員屬性。很好理解,不多解釋。
依賴: 假設有兩個類:A和B,類B的某個成員方法的參數有類A,則類B依賴類A (也就是常說的uses-a,這里應該是uses-b)。
<?php class A { public function one() { return 'one'; } } class B { public function two(A $a) { return $a->one(); } } $b_obj = new B(); echo $b_obj->two(new A());
關聯: 強依賴關系,當所依賴的類已經成為了類成員的時候,此時會被加載到內存當中的,而不是參數的時候(如果是單純的依賴,那么依賴所在的方法如果不調用,就不會發生什么),關聯有一對多,多對多之分,也有單向雙向之分,比如單向一對多。
<?php class A { public function one() { return 'one'; } } class B { public $obj_a; public function two() { $this->obj_a = new A(); return $this->obj_a->one(); } } $b_obj = new B(); print_r($b_obj->two());
聚合: A和B的關系是整體和局部的關系(has-a),整體和局部是可以分開的。DemoDateTime包含了DemoDate和DemoTime,也就是DemoDateTime聚合了DemoDate和DemoTime。
<?php class DemoDate { public function getDate() { return date("Y/m/d"); } } class DemoTime { public function getTime() { return date("H:i:s"); } } class DemoDateTime { public function getDateTime() { $date_obj = new DemoDate(); $time_obj = new DemoTime(); $datetime = $date_obj->getDate() . ' ' . $time_obj->getTime(); return $datetime; } } $datetime_obj = new DemoDateTime(); echo $datetime_obj->getDateTime();
組合: 組合關系也是整體和部分的關系,但它是強聚合關系。可以理解為各個部分不能離開整體,離開了就要出問題。
就是繼承。
實現就是一個抽象類被其它類實現。
通俗講就是多用用接口,把接口作為定義大骨架,來使用,剩下的細節,交給實現接口的類去使用,也就是將定義與實現分離,需要開發者擁有分離的抽象思想。
(以上內容為原創,以下內容全部來源于網絡,然后進行整合,感謝各位網友的回復。) 接口應有兩類:第一類是對一個體的抽象,它可對應為一個抽象體(abstract class);第二類是對一個體某一方面的抽象,即形成一個抽象面(interface),一個體有可能有多個抽象面。 操作數據庫就必須會用到 Insert Update Select ,所以Insert Update Select 做成接口 但是,每個功能操作的內容又不一樣,所以,做一個抽象類繼承接口然后抽象類的派生類去實現抽象類的具體方法。
接口是一組規則的集合,它規定了實現本接口的類或接口必須擁有的一組規則 抽象類和接口的區別在于使用動機。使用抽象類是為了代碼的復用,而使用接口的動機是為了實現多態性。
如果這個概念在我們腦子中是確確實實存在的,就用抽象類。 否則的話,如果這個概念僅僅是一方面的特性,比如會飛的,能跑的,這些我們就設置為接口。 兩個概念模糊,不知道設置為抽象類還是接口的時候,一般我們設置為接口,原因是我們實現了這個接口還可以繼承。
抽象類適合用來定義某個領域的固有屬性,也就是本質,接口適合用來定義某個領域的擴展功能。 當需要為一些類提供公共的實現代碼時,應優先考慮抽象類。因為抽象類中的非抽象方法可以被子類繼承下來,使實現功能的代碼更簡單。 當注重代碼的擴展性跟可維護性時,應當優先采用接口。①接口與實現它的類之間可以不存在任何層次關系,接口可以實現毫不相關類的相同行為,比抽象類的使用更加方便靈活;②接口只關心對象之間的交互的方法,而不關心對象所對應的具體類。接口是程序之間的一個協議,比抽象類的使用更安全、清晰。一般使用接口的情況更多。
當描述一組方法的時候使用接口 當描述一個虛擬的物體的時候使用抽象類
抽象類是跟繼承類是“is”的關系,接口和實現類是"like"的關系,從這個角度出發,應該可以看出很多東西。其它的區別只是一些語法,用法規范上的區別,核心思想就是這個is-like區別。
到此,關于“面向對象3個特性7個原則6種關系是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。