設計模式之黎克特制替換原則

2021-09-29 15:51:47 字數 1776 閱讀 9820

黎克特制替換原則的定義

黎克特制替換原則(liskov substitution principle,lsp)由麻省理工學院電腦科學實驗室的裡斯科夫(liskov)女士在 1987 年的「物件導向技術的高峰會議」(oopsla)上發表的一篇文章《資料抽象和層次》(data abstraction and hierarchy)裡提出來的,她提出:繼承必須確保超類所擁有的性質在子類中仍然成立。

黎克特制替換原則的作用

黎克特制替換原則的主要作用如下:

黎克特制替換原則是實現開閉原則的重要方式之一。

它克服了繼承中重寫父類造成的可復用性變差的缺點。

它是動作正確性的保證。即類的擴充套件不會給已有的系統引入新的錯誤,降低了**出錯的可能性。

黎克特制替換原則的實現方法

黎克特制替換原則通俗來講就是:子類可以擴充套件父類的功能,但不能改變父類原有的功能。也就是說:子類繼承父類時,除新增新的方法完成新增功能外,盡量不要重寫父類的方法。

如果通過重寫父類的方法來完成新的功能,這樣寫起來雖然簡單,但是整個繼承體系的可復用性會比較差,特別是運用多型比較頻繁時,程式執行出錯的概率會非常大。

如果程式違背了黎克特制替換原則,則繼承類的物件在基類出現的地方會出現執行錯誤。這時其修正方法是:取消原來的繼承關係,重新設計它們之間的關係。

關於黎克特制替換原則的例子,最有名的是「正方形不是長方形」。當然,生活中也有很多類似的例子,例如,企鵝、鴕鳥和幾維鳥從生物學的角度來劃分,它們屬於鳥類;但從類的繼承關係來看,由於它們不能繼承「鳥」會飛的功能,所以它們不能定義成「鳥」的子類。同樣,由於「氣球魚」不會游泳,所以不能定義成「魚」的子類;「玩具炮」炸不了敵人,所以不能定義成「炮」的子類等。

下面以* 「幾維鳥不是鳥 」*為例來說明黎克特制替換原則。

分析:鳥一般都會飛行,如燕子的飛行速度大概是每小時 120 千公尺。但是紐西蘭的幾維鳥由於翅膀退化無法飛行。假如要設計乙個例項,計算這兩種鳥飛行 300 千公尺要花費的時間。顯然,拿燕子來測試這段**,結果正確,能計算出所需要的時間;但拿幾維鳥來測試,結果會發生「除零異常」或是「無窮大」,明顯不符合預期,其類圖如圖 1 所示。

程式**如下:

package principle;

public

class

lsptest

catch

(exception err)}}

//鳥類

class

bird

public

double

getflytime

(double distance)

}//燕子類

class

swallow

extends

bird

//幾維鳥類

class

brownkiwi

extends

bird

}

程式執行結果如下:

如果飛行300公里:

燕子將飛行2.5小時.

幾維鳥將飛行infinity小時。

程式執行錯誤的原因是:幾維鳥類重寫了鳥類的 setspeed(double speed) 方法,這違背了黎克特制替換原則。正確的做法是:取消幾維鳥原來的繼承關係,定義鳥和幾維鳥的更一般的父類,如動物類,它們都有奔跑的能力。幾維鳥的飛行速度雖然為 0,但奔跑速度不為 0,可以計算出其奔跑 300 千公尺所要花費的時間。其類圖如圖 2 所示。

設計模式 之黎克特制替換原則

一 定義 所有引用基類的地方必須能透明的使用其子類的物件。怎麼理解呢?簡單來說,只要父類能出現的地方子類就可以出現,而且替換後不會產生任何錯誤或者異常,反之不然!二 好處 這樣設計的程式,健壯性大大增加,版本公升級時也可以保持非常好的相容性,及時增加子類,原有子類也可以繼續執行而不會受到影響。三 示...

設計模式之黎克特制替換原則

what liskov substitution principle lsp 任何父類出現的地方,子類一定可以出現。why lsp是ocp原則的規範。ocp原則的關鍵的是抽象,而繼承關係又是抽象的一種具體表現。how 當子類不能完整的實現父類父類的方法,那麼建議斷開父子關係,採用依賴,聚合,組合等關...

設計模式 黎克特制替換原則

設計模式 黎克特制替換原則 物件導向的語言繼承必不可少的,有如下優點 共享,減少建立類的工作量 提高 的重用性 提高 的可擴充套件性 提高 的可擴充套件性 提高產品 的開放性 繼承侵入性 只要繼承,必須擁有父類的內容 降低 的靈活性,子類必須擁有父類的屬性和方法 增強耦合性。黎克特制替換原則,為繼承...