一.簡(jiǎn)稱
英文全稱是Liskov Substitution Principle, 縮寫是LSP
二.定義
如果對(duì)每一個(gè)類型為S的對(duì)象O1,都有類型為T的對(duì)象O2,使得以T定義的所有程序P在所有的對(duì)象O1都替換成O2時(shí)静尼,程序P的行為沒(méi)有發(fā)生變化别伏,那么類型S是類型T的子類型。
簡(jiǎn)單的說(shuō)就是所有引用基類的地方必須能透明地使用其子類的對(duì)象触徐。通俗點(diǎn)講,只要父類能出現(xiàn)的地方子類就可以出現(xiàn),而且替換為子類也不會(huì)產(chǎn)生任何錯(cuò)誤或異常,使用者根本就不需要知道是父類還是子類悼吱,但是反過(guò)來(lái)就不行,有子類出現(xiàn)的地方良狈,父類未必就能適應(yīng)舆绎。總的來(lái)說(shuō)就是抽象们颜。
比如從Window和View的關(guān)系來(lái)看
//窗口類
public class Window{
public void show(View child){
child.draw();
}
}
//測(cè)量視圖的寬高為公用代碼,繪制實(shí)現(xiàn)交給具體的子類
public abstract class View{
public abstract void draw();
public void measure(int width,int height){
//測(cè)量視圖大小
}
}
//TextView 的具體實(shí)現(xiàn)
public class TextView extends View{
public void draw(){
}
}
//Button的具體實(shí)現(xiàn)
public class Button extends View{
public void draw(){
}
}
Window依賴于View,而View定義了一個(gè)視圖抽象猎醇,measure是各個(gè)子類共享的方法窥突,子類覆寫View的draw方法實(shí)現(xiàn)自己特有的功能,任何繼承自View類的子類都可以設(shè)置給View方法硫嘶,就是所說(shuō)的里氏替換阻问。通過(guò)里氏替換,就可以定義各式各樣的View,然后傳遞給Window,Window負(fù)責(zé)將View顯示到屏幕上沦疾。
三.核心原理
核心是抽象称近,而抽象又依賴于繼承特性第队。
繼承的優(yōu)缺點(diǎn):
優(yōu)點(diǎn):
(1)代碼復(fù)用,減少創(chuàng)建類的成本刨秆,每個(gè)子類都擁有父類的方法和屬性
(2)子類和父類基本相似凳谦,但又與父類有所區(qū)別
(3)提高代碼的可擴(kuò)展性
缺點(diǎn):
(1)只要繼承就必須擁有父類的所有屬性和方法
(2)可能造成子類代碼冗余、靈活度降低衡未,因?yàn)樽宇惐仨殦碛懈割惖膶傩院头椒ā?br>
在實(shí)際使用中要根據(jù)具體的情況來(lái)看要不要使用繼承尸执。
四.注意事項(xiàng)
(1)子類的所有方法必須在父類中聲明,或子類必須實(shí)現(xiàn)父類中聲明的所有方法缓醋。因?yàn)楦鶕?jù)里氏替換原則如失,為了保證系統(tǒng)的擴(kuò)展性,在程序中通常使用父類來(lái)進(jìn)行定義送粱,如果一個(gè)方法只存在子類中褪贵,在父類中不提供相應(yīng)的聲明,則無(wú)法在以父類定義的對(duì)象中使用該方法抗俄。
(2)盡量把父類設(shè)計(jì)為抽象類或接口脆丁,讓子類繼承父類或?qū)崿F(xiàn)父接口,并實(shí)現(xiàn)父類中聲明的方法橄镜,運(yùn)行時(shí)偎快,子類實(shí)例替換父類實(shí)例,我們可以很方便地?cái)U(kuò)展系統(tǒng)的功能洽胶,同時(shí)無(wú)須修改原有子類的代碼晒夹,增加新的功能可以通過(guò)增加一個(gè)新的子類來(lái)實(shí)現(xiàn)。里氏替換原則是開閉原則的具體實(shí)現(xiàn)手段之一姊氓。
總結(jié)
里氏替換原則和開閉原則一般都是一起使用的丐怯,通過(guò)里氏替換來(lái)達(dá)到對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉的效果翔横。