生活中的面向對象

面向對象思想

感悟:要想成爲合格工程師,必須擁有面向對象思維

初級工程師和高級工程師以及架構師最大的區別就是等級越高看問題的角度就不一樣,猶如初級工程師寫系統完全就是面向過程 if else寫滿整個類,而且類之間的耦合性很大,不好維護,牽一髮而動全身,擴展性很不好。他們站在角度就是能完成功能需求,但是高級工程師以及架構師站在項目角度,考慮未來需求變化和如何做到可維護性、可複用、可擴展(當然這裏從代碼層面,還有就是從系統架構層面考慮後面單設欄目進行分析)。

面向對象特性

  • 封裝
  • 繼承
  • 多態

封裝

將獨立模塊(可能是獨個方法或多個類,甚至一個系統)邏輯封裝起來,便於複用,維護。

儘量讓依賴方知道的越少越好,將複雜邏輯封裝在一個類中的方法中或模塊中。 例如根據需要傳入對應的參數,然後獲取相應的結果,獲取結果過程我們並不care,我只想要結果是什麼,複雜的邏輯封裝起來就好。

繼承

將公共邏輯(包括屬性、方法)放在一個父類中,然後不同的子類繼承父類重寫其方法,因此有不同的表現。依賴方只需要拿到抽象父類,並不需要知道具體實現類,降低模塊之間的耦合性。

出現父類的地方一定可以被其他子類替換掉,這個就是後面講到的面向對象四大設計原則中的里氏替換原則

多態

編譯時多態:方法的重載 方法簽名(方法名+方法參數類型+方法參數個數,返回類型不能唯一區分方法)

運行時多態:在運行的過程中,jvm才知道抽類的引用具體指向那個子類對象,當調用抽象類的方法時實際上調用的是該子類中的方法

類和對象

java中的類型:類、接口、數組、基本類型 四種類型,前三種屬於引用類型,可以實例化對象

類組成:屬性(類型(java中的類型) 屬性名)、方法(行爲 返回類型 方法名(類型 參數名…))、內部類

例如 游泳這個方法,A人和B人是不同對象 A的體力(類的屬性值)好 B的體力弱些 那麼游泳這個行爲表現就不一樣,A比B遊的遠

編程和生活結合

1、利用面向對象思想設計系統步驟:

  • 系統中的模塊

在編程中我們要實現一個系統或完成某個功能首先應該考慮由那些模塊組成和關係,然後從中抽出公共模塊。

  • 模塊中的類

而設計具體的某個模塊的實現時應該考慮需要那些類和類與類之間的關係以及類的屬性和方法,例如A類某中行爲需要依賴B類來完成,這個時候A類中的屬性具有B類。爲了降低耦合和便於擴展這裏依賴的是一個抽象類或接口。

  • 系統中的對象

上面的類只是一個概念,要想完成一個功能必須要以上面設計的類爲模版創建對象來實現。當然對於一個static 屬性和方法除外因爲這個屬性和方法是類獨有的(也就是所有該類對象共享)

需要完成一個這樣一個功能: 修改數據庫用戶id=8 name=“haha”,這個時候需要有個User類 屬性 id name有get set方法,還有一個UserDAO類有個updateUser(User user)更新user表數據的方法,這個步驟就是設計類, 第二步就是創建id=8 name="haha"User對象,然後還創建UserDAO對象,將User對象傳入updateUser方法中,這樣就完成了更新用戶id=8名字這麼個需求。

2、生活中的面向對象

在我們生態系統中,我眼前的都可以看作是對象,Thinking in java中說到Every thing is object一點都沒說,人類的衣食住行,等等生活就可以看作成對象,從前面講到一個對象必須要有一個類模版,所以更抽象一步我們需要知道有那些類。

例如:你、他、我都是對象由人"類"創造而成的,人類家離上班地方很遠,需要乘交通工具上班,這個時候人類去上班這個行爲需要依賴交通工具類(具體對象可以是地鐵、汽車、自行車等)依賴抽象類好處更容易擴展。 人類由手類組成的(將手類看作人類的屬性),頭髮類等其他類組成,當構建一個人類對象時需要傳入對應的依賴和關聯的對象(地鐵對象、手對象、頭髮對象),最後這個人對象就可以完成人類具有的動作了,哈哈?這就是你,不一樣的燈火 human!

面向對象設計原則

  • 單一職責
  • 開放封閉
  • 依賴倒置
  • 里氏替換
  • 迪米特法則

單一職責

一個類確保只有一個原因來引起它變化,如果多於一個原因的話就說明該類承擔多於一個職責,應考慮進行拆分。單一職責可以保證易於維護,便於擴展和複用,降低耦合性。

例如:設計一個計算器功能,然後A類中具有界面邏輯和計算邏輯,這個明顯有兩個原因引起A類變化,如果界面邏輯改變需要改動A類,如果計算邏輯改動了也要改動A類,明顯就不符合單一職責原則,因此就需要將界面邏輯和計算邏輯拆分成兩個類,這樣計算邏輯也很容易被複用。

開放封閉

對(類、模塊、方法)修改封閉,但是擴展是開放的。 類或模塊依賴的是抽象,當需要增加一種具體實現只需要從抽象中擴展,無需更改原來的類,這個就需要在繼承、多態、接口基礎上來實現的。

依賴倒置

計算機系統內部也引用了面向對象思想:將 內存、cpu、主板、磁盤可以看作成類,他們之間都是根據對應的接口進行設計的(例如內存需要使用主板某個方法,此時需要依賴抽象的主板的方法) 假如內存使用了具體某個品牌的主板,如果內存壞了,替換內存就會導致替換主板的尷尬。

單一職責原則:例如內存壞了就換內存,不應該成爲替換cpu的原因

開閉原則:例如內存不夠了,在主板上有足夠的插槽時可以添加內存條,如果磁盤不夠時可以通過pc usb接口接上添加移動硬盤

1、高層模塊不應該依賴底層模塊,高層和底層模塊都要依賴抽象類(接口)

例如 內存、cpu都依賴於具體的主板,如果主板一壞導致cpu、內存都不可用,這是不合理的,高層模塊依賴底層模塊會導致高層模塊複用性很差,如果都依賴抽象的話,高層和底層都可以複用

2、抽象不依賴細節,細節依賴抽象

也就是面向接口進行編程,不需要care具體的實現,只需調用對方提供的接口,傳入相應參數獲取對應的值

里氏替換

父類的抽象方法子類需要實現,但是已經實現的方法,子類不應該重寫。 也就是父類出現的地方可以使用其他子類對象進行替換,這也是實現多態,開閉原則的基礎。

迪米特法則

迪米特法則也稱最少知識原則,用於降低類之間的耦合度。如果A類和C類沒有必要進行彼此通訊,如果A類調用C類方法m1,可以通過第三者轉發調用。這樣就大大提高了代碼複用,如果想要修改C類的m1那麼之前如果A類、B類直接引用C類調用方法m1,那麼導致都需要進行該動,現在如果通過第三者進行轉發,只需要改動第三者就行,A、B類無需更改。

還有一個好處就是,第三者可以控制將這次的調用委派給那個類,靈活性更高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章