1. 程式人生 > >設計模式之禪(里氏替換原則)2018-10-19

設計模式之禪(里氏替換原則)2018-10-19

介面與抽象類的區別:

介面卡模式:使用不同介面的類所提供的服務為客戶端提供它所期望的介面。

實現:

有一個 MediaPlayer 介面和一個實現了 MediaPlayer 介面的實體類 AudioPlayer。預設情況下,AudioPlayer 可以播放 mp3 格式的音訊檔案。

我們還有另一個介面 AdvancedMediaPlayer 和實現了 AdvancedMediaPlayer 介面的實體類。該類可以播放 vlc 和 mp4 格式的檔案。

想要讓 AudioPlayer

 播放其他格式的音訊檔案。為了實現這個功能,我們需要建立一個實現了 MediaPlayer 介面的介面卡類 MediaAdapter,並使用 AdvancedMediaPlayer 物件來播放所需的格式。

AudioPlayer 使用介面卡類 MediaAdapter 傳遞所需的音訊型別,不需要知道能播放所需格式音訊的實際類。AdapterPatternDemo,我們的演示類使用 AudioPlayer 類來播放各種格式。

里氏替換原則(可以理解為,子類擁有父類的全部功能;父類出現的任何地方都能被子類所代替;子類必須完全實現父類的方法。)

● 第一種定義,也是最正宗的定義:If for each object o1 of type S there is an object o2 of
type T such that for all programs P defined in terms of T,the behavior of P is unchanged when o1 is
substituted for o2 then S is a subtype of T.(如果對每一個型別為S的物件o1,都有型別為T的對
象o2,使得以T定義的所有程式P在所有的物件o1都代換成o2時,程式P的行為沒有發生變
化,那麼型別S是型別T的子型別。)
● 第二種定義:Functions that use pointers or references to base classes must be able to use
objects of derived classes without knowing it.(所有引用基類的地方必須能透明地使用其子類的
物件。)
第二個定義是最清晰明確的,通俗點講,只要父類能出現的地方子類就可以出現,而且
替換為子類也不會產生任何錯誤或異常,使用者可能根本就不需要知道是父類還是子類。但
是,反過來就不行了,有子類出現的地方,父類未必就能適應。

●程式碼共享,減少建立類的工作量,每個子類都擁有父類的方法和屬性;
● 提高程式碼的重用性;
● 子類可以形似父類,但又異於父類,“龍生龍,鳳生鳳,老鼠生來會打洞”是說子擁有父的“種”,“世界上沒有兩片完全相同的葉子”是指明子與父的不同;
● 提高程式碼的可擴充套件性,實現父類的方法就可以“為所欲為”了,君不見很多開源框架的擴充套件介面都是通過繼承父類來完成的;
● 提高產品或專案的開放性。

繼承的缺點如下:
● 繼承是侵入性的。只要繼承,就必須擁有父類的所有屬性和方法;
● 降低程式碼的靈活性。子類必須擁有父類的屬性和方法,讓子類自由的世界中多了些約束;
● 增強了耦合性。當父類的常量、變數和方法被修改時,需要考慮子類的修改,而且在缺乏規範的環境下,這種修改可能帶來非常糟糕的結果——大段的程式碼需要重構。

Java使用extends關鍵字來實現繼承,它採用了單一繼承的規則