2里氏替換原則


里氏替換原則

里氏替換原則的英文名稱是:Liskov Substitution Principle,簡稱LSP(老色批)。
 

1里氏替換原則的定義

英文定義有兩種:
①If for each object o1 of type S there is an object o2 of type T such thatfor all programs P defined in terms of S,the behavior of P is unchangedwhen o1 is substituted for o2 then T is a subtype of S.
這個定義是最正宗的定義,意思是:如果對一個類型為S的對象o1,都有類型為T的對象o2,使得以S定義的所有程序P在所有的對象o1都代換成o2時,程序P的行為沒有發生變化,那么類型T是類型S的子類型。
②Functions that use pointers or references to base classes must be ableto use objects of derived classes without knowing it.
第二個定義意思是:所有引用基類的地方必須能透明地使用其子類對象。清晰明確地說明只要父類能出現的地方子類就可以出現,而且替換為子類也不會產生任何錯誤或異常,使用者可能根本就不需要知道父類還是子類;但是反過來則不可以,有子類的地方,父類未必就能適應。
 
 里氏代換原則中說,任何基類可以出現的地方,子類一定可以出現。LSP 是繼承復用的基石,只有當派生類可以替換掉基類,且軟件單位的功能不受到影響時,基類才能真正被復用,而派生類也能夠在基類的基礎上增加新的行為。里氏代換原則是對開閉原則的補充。實現開閉原則的關鍵步驟就是抽象化,而基類與子類的繼承關系就是抽象化的具體實現, 所以里氏代換原則是對實現抽象化的具體步驟的規范
 
繼承存在很多優點,但也存在缺陷,而 “里氏替換原則”可以減少"弊"所帶來的麻煩
優點:
■ 代碼共享,減少創建類的工作量,每個子類都擁有父類的方法和屬性;
■ 提高代碼的可重用性;
■ 提高代碼的可擴展性;
■ 提高產品或項目的開放性。
 
缺陷:
■ 繼承是入侵式的。只要繼承,就必須擁有父類的所有屬性和方法;
■ 降低代碼的靈活性。子類必須擁有父類的屬性和方法,使子類受到限制;
■ 增強了耦合性。當父類的常量、變量和方法修改時,必須考慮子類的修改,這種修改可能造成大片的代碼需要重構。
 

2里氏替換原則的應用

在編譯期間,java語言編輯器會檢查一個程序是否符合里氏替換原則,這是一個無關實現的、純語法意義上的檢查。里氏替換原則要求是使用基類的地方,子類一定適用,因此子類必須具備基類的全部接口。或者說,子類型的接口必須包括全部的基類的接口,而且還有可能更寬。如果一個java程序破壞這一條件,java編輯器就會在編譯程序時拋出錯誤提示,並停止編譯。例如,一個基類Base聲明了一個public方法改換成private或procted。
即子類 不能使用一個 低訪問權限的方法 覆蓋基類中的 高訪問權限的方法。
里氏替換原則為良好的繼承定義了一個規范,它包含4層含義:
■ 子類必須完全實現父類的方法;
■ 子類可以有自己的個性;
■ 覆蓋或實現父類的方法時輸入參數可以被放大;
■ 覆蓋或實現父類的方法時輸出結果可以被縮小。
例:Animal 是一個表示動物的抽象類,只要是動物就都能動,因此提供一個抽象的move()方法;Horse和Bird都是Animal的子類。
 
下面編寫一個測試類
 1 public class Test{
 2     public static void main(String[] args){
 3         //聲明一個基類對象
 4         Animal animal;
 5         //使用基類對象指向子類
 6         animal = new Horse();
 7         animal.move;
 8         animal = new Bird();
 9         animal.move;
10         // Horse h = new Animal(); //錯誤
11     }
12 }
View Code

 

上述代碼中,使用基類對象指向子類是允許的,但反過來,使用子類對象指向父類則違反里氏替換原則,會出現錯誤。
 
注意按照里氏替換原則,當多個類之間存在繼承關系時,通常應該使用父類或接口來指向子類的對象(除非需要使用子類特有的方法),這更利於提高系統的可擴展性。
 
在設計模式中體現里氏替換原則的有如下幾個模式:
■ 策略模式
■ 組合模式
■ 代理模式






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM