面向物件原則之里氏替換原則
轉載請註明出處:http://blog.csdn.net/feibendexiaoma/article/details/74391028
一.簡稱
英文全稱是Liskov Substitution Principle, 縮寫是LSP
二.定義
如果對每一個型別為S的物件O1,都有型別為T的物件O2,使得以T定義的所有程式P在所有的物件O1都替換成O2時,程式P的行為沒有發生變化,那麼型別S是型別T的子型別。
簡單的說就是所有引用基類的地方必須能透明地使用其子類的物件。通俗點講,只要父類能出現的地方子類就可以出現,而且替換為子類也不會產生任何錯誤或異常,使用者根本就不需要知道是父類還是子類,但是反過來就不行,有子類出現的地方,父類未必就能適應。總的來說就是抽象。
比如從Window和View的關係來看
//視窗類
public class Window{
public void show(View child){
child.draw();
}
}
//測量檢視的寬高為公用程式碼,繪製實現交給具體的子類
public abstract class View{
public abstract void draw();
public void measure(int width,int height){
//測量檢視大小
}
}
//TextView 的具體實現
public class TextView extends View{
public void draw(){
}
}
//Button的具體實現
public class Button extends View{
public void draw(){
}
}
Window依賴於View,而View定義了一個檢視抽象,measure是各個子類共享的方法,子類覆寫View的draw方法實現自己特有的功能,任何繼承自View類的子類都可以設定給View方法,就是所說的里氏替換。通過里氏替換,就可以定義各式各樣的View,然後傳遞給Window,Window負責將View顯示到螢幕上。
三.核心原理
核心是抽象,而抽象又依賴於繼承特性。
繼承的優缺點:
優點:
(1)程式碼複用,減少建立類的成本,每個子類都擁有父類的方法和屬性
(2)子類和父類基本相似,但又與父類有所區別
(3)提高程式碼的可擴充套件性
缺點:
(1)只要繼承就必須擁有父類的所有屬性和方法
(2)可能造成子類程式碼冗餘、靈活度降低,因為子類必須擁有父類的屬性和方法。
在實際使用中要根據具體的情況來看要不要使用繼承。
四.注意事項
(1)子類的所有方法必須在父類中宣告,或子類必須實現父類中宣告的所有方法。因為根據里氏替換原則,為了保證系統的擴充套件性,在程式中通常使用父類來進行定義,如果一個方法只存在子類中,在父類中不提供相應的宣告,則無法在以父類定義的物件中使用該方法。
(2)儘量把父類設計為抽象類或介面,讓子類繼承父類或實現父介面,並實現父類中宣告的方法,執行時,子類例項替換父類例項,我們可以很方便地擴充套件系統的功能,同時無須修改原有子類的程式碼,增加新的功能可以通過增加一個新的子類來實現。里氏替換原則是開閉原則的具體實現手段之一。
總結
里氏替換原則和開閉原則一般都是一起使用的,通過里氏替換來達到對擴充套件開放,對修改關閉的效果。