02 黎克特制替換原則 LSP

2022-09-18 22:00:23 字數 1453 閱讀 3379

lsp , liskov substitution principle , 黎克特制替換原則

所有引用基類(父類)的地方必須能透明地使用其子類的物件。通俗講:子類可以擴充套件父類的功能,但不能改變父類原有的功能

是實現開閉原則的重要方式之一

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

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

繼承是侵入性的,只要繼承就必須擁有父類的所有屬性和方法

可能造成子類**冗餘,靈活性降低,因為必須擁有父類的屬性和方法

黎克特制替換原則的核心原理是抽象,抽象又依賴於繼承這個特性

子類必須完全實現父類的方法

子類可以有自己的修改(重寫,過載,新增父類中沒有的方法)

子類中override的方法,傳入引數型別必須是與父類相同型別,或是子型別

子類中override的方法,返回型別必須是與父類相同型別,或是子型別

舉例說明兩個數相減,由a類負責

class a 

}public class lspclient

}輸出結果:

5 - 3 = 2

100 - 10 = 90

此時需要新加乙個功能:兩數相加,然後再與100求和,由b類負責

class a 

}class b extends a

public int func2(int a, int b)

}public class lspclient

}輸出結果:

5-3=8

100-10=110

50+20+100=170

此時發現原本執行正常的相減功能發生了錯誤,原因是子類b重寫了父類a中的func1方法,從兩數相減變成了兩數相加。引用基類a完成的功能,換成子類b之後,發生了異常。在實際程式設計中,我們常常會通過重寫父類的方法來完成新的功能,這樣寫起來雖然簡單,但是整個繼承體系的可復用性會比較差,特別是運用多型比較頻繁時,程式執行出錯的機率非常大。如果非要重寫父類的方法,比較通用的做法是:原來的父類和子類都繼承乙個更通俗的基類,原有的繼承關係去掉,採用依賴、聚合,組合等關係代替。

黎克特制替換原則通俗的來講就是:子類可以擴充套件父類的功能,但不能改變父類原有的功能。包含以下4層含義:

子類可以實現父類的抽象方法,但不能覆蓋父類的非抽象方法。

子類中可以增加自己特有的方法。

當子類的方法過載父類的方法時,方法的前置條件(即方法的形參)要比父類方法的輸入引數更寬鬆。

當子類的方法實現父類的抽象方法時,方法的後置條件(即方法的返回值)要比父類更嚴格。

看上去很不可思議,因為我們會發現在自己程式設計中常常會違反黎克特制替換原則,程式照樣跑的好好的。所以大家都會產生這樣的疑問,假如我非要不遵循黎克特制替換原則會有什麼後果?後果就是:你寫的**出問題的機率將會大大增加。

P3 黎克特制替換原則 LSP

黎克特制替換原則 liskov substitution principle 簡稱lsp.美國電腦科學barbara liskov提出定義如下 如果對每乙個型別為s的物件o1,都有型別為t的物件o2,使得以t定義的所有程式p在所有的物件o1代換o2時,程式p的行為沒有變化,那麼型別s是型別t的子型別...

黎克特制替換原則,LSP

所有引用基類的地方必須能夠透明地使用其子類的物件。通俗點講,只要父類能出現的地方子類就可以出現,而且替換為子類也不會產生任務異常。我們知道物件導向語言的三大特性就是繼承 封裝 多台,黎克特制替換原則就是依賴於繼承 多型,建立抽象,通過抽象建立規範,在執行時替換成具體的物件,保證系統的拓展性 靈活性。...

2 黎克特制替換原則

肯定有不少人跟我剛看到這項原則的時候一樣,對這個原則的名字充滿疑惑。其實原因就是這項原則最早是在1988年,由麻省理工學院的一位姓裡的女士 barbara liskov 提出來的。如果對每乙個型別為 t1的物件 o1,都有型別為 t2 的物件o2,使得以 t1定義的所有程式 p 在所有的物件 o1 ...