理論性知識學習
里氏替換原則,Liskov Substitution principle(LSP)。測試
抽象定義是下面這樣的設計
若是對每個類型爲T1的對象O1,都有類型爲T2的對象O2,使得以T1定義的全部程序P在全部的對象O1都替換成O2時,程序P的行爲沒有發生變化,那麼類型T2是類型T1的子類型。對象
通俗地解釋一下blog
一個軟件實體若是適用一個父類的話,那必定適用於其子類,全部引用父類的地方必須能透明地使用其子類的對象,子類對象可以替換父類對象,而程序邏輯不變。繼承
引伸一下,若是子類替換父類,還必須保證程序邏輯不變,就必須知足如下幾點。ip
增強程序的健壯性,同時變動時能夠作到很是好的兼容性。ci
提升程序的維護性,擴展性,下降需求變動時引入的風險。編譯器
代碼實戰1it
實現一個正方形繼承長方形的場景,由於正方形是一種特殊的長方形。
定義一個長方形,以下圖
定義一個正方形,以下圖,重寫了父類的方法。
最後執行測試方法,當寬大於等於高時,就改變寬和高。以下圖
當用子類正方形替換父類時,程序就會進入無限循環,以下圖
根據以上得出,子類能夠實現父類的抽象方法,但不能覆蓋父類的非抽象方法
代碼實戰2
首先定義一個簡單的父類,以下圖
而後定義一個子類,子類的入參類型Map比父類的入參HashMap寬鬆,以下圖
最後測試以下圖
由測試結果能夠看出,child類徹底能夠替換base類去執行。遵循了裏式替換原則,
即當子類的方法重載父類的方法時,方法的前置條件(即方法的輸入,入參)要比父類方法的輸入參數更寬鬆。
代碼實戰3
仍是定義一個簡單的父類,方法返回類型爲HashMap,以下圖
定義一個子類,實現父類抽象方法時,返回值類型爲Map,編譯器就會直接報錯,以下圖
根據以上能夠得出結論
當子類的方法實現父類的方法時(重寫,重載或實現抽象方法),方法的後置條件(方法的輸出,返回值)要比父類更嚴格或相等。
我的總結
一開始學習裏式替換原則時,也是不明白。最後也是慢慢理解透的。總結起來就是
子類能夠替換父類,替換後,不能改變程序的運行邏輯。
也歡迎你們在評論區留下本身的見解!