首頁>技術>

理論性知識

定義

里氏替換原則,Liskov Substitution principle(LSP)

抽象定義是下面這樣的

如果對每一個型別為T1的物件O1,都有型別為T2的物件O2,使得以T1定義的所有程式P在所有的物件O1都替換成O2時,程式P的行為沒有發生變化,那麼型別T2是型別T1的子型別。

通俗地解釋一下

一個軟體實體如果適用一個父類的話,那一定適用於其子類,所有引用父類的地方必須能透明地使用其子類的物件,子類物件能夠替換父類物件,而程式邏輯不變。

引申一下,如果子類替換父類,還必須保證程式邏輯不變,就必須滿足以下幾點。

子類可以實現父類的抽象方法,但不能覆蓋父類的非抽象方法。 子類中可以增加自己特有的方法。 當子類的方法過載父類的方法時,方法的前置條件(即方法的輸入,入參)要比父類方法的輸入引數更寬鬆。當子類的方法實現父類的方法時(重寫,過載或實現抽象方法),方法的後置條件(方法的輸出,返回值)要比父類更嚴格或相等。 優點

加強程式的健壯性,同時變更時可以做到非常好的相容性。

提高程式的維護性,擴充套件性,降低需求變更時引入的風險。

程式碼實戰1

實現一個正方形繼承長方形的場景,因為正方形是一種特殊的長方形。

定義一個長方形,如下圖

定義一個正方形,如下圖,重寫了父類的方法。

最後執行測試方法,當寬大於等於高時,就改變寬和高。如下圖

當用子類正方形替換父類時,程式就會進入無限迴圈,如下圖

根據以上得出,子類可以實現父類的抽象方法,但不能覆蓋父類的非抽象方法

程式碼實戰2

首先定義一個簡單的父類,如下圖

然後定義一個子類,子類的入參型別Map比父類的入參HashMap寬鬆,如下圖

最後測試如下圖

由測試結果可以看出,child類完全可以替換base類去執行。遵循了裡式替換原則,

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

程式碼實戰3

還是定義一個簡單的父類,方法返回型別為HashMap,如下圖

定義一個子類,實現父類抽象方法時,返回值型別為Map,編譯器就會直接報錯,如下圖

根據以上可以得出結論

當子類的方法實現父類的方法時(重寫,過載或實現抽象方法),方法的後置條件(方法的輸出,返回值)要比父類更嚴格或相等。

個人總結

一開始學習裡式替換原則時,也是不明白。最後也是慢慢理解透的。總結起來就是

子類可以替換父類,替換後,不能改變程式的執行邏輯。

15
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 鴻蒙核心原始碼分析(排程故事篇) | 西門和金蓮的那點破事