設計模式之里氏替換原則
里氏替換原則(LSP: Liskov Substitution Principle)
定義:####:
- 子類可以擴展父類的功能,但不能改變父類的原有功能
- 子類可以繼承父類琅绅,但是不能覆蓋父類的非抽象方法
- 程序中將任意一個基類對象替換成子類對象痘系,程序不會產(chǎn)生任何異常挡爵。反過來則不成立。
- 每一個使用基類的地方,都可以透明的使用子類對象
- 里氏代換原則是實現(xiàn)開閉原則的重要方式之一,由于使用基類對象的地方都可以使用子類對象魏割,因此在程序中盡量使用基類類型來對對象進行定義,而在運行時再確定其子類類型钢颂,用子類對象來替換父類對象钞它。
- OOP多態(tài)的使用
public class People
{
public void SayHIStandard()
{
Console.WriteLine("普通話:你好");
}
}
public class HubeiPeople : People
{
public new void SayHIStandard() //破壞父類的標準,覆蓋了父類的方法
{
Console.WriteLine("湖北話:你好");
}
}
public class SichuanPeople : People
{
public new void SayHIStandard() //破壞父類的標準殊鞭,覆蓋了父類的方法
{
Console.WriteLine("四川話:你好");
}
}
People people = new People();
people.SayHIStandard();
HubeiPeople hbPeople = new HubeiPeople();
people.SayHIStandard(); //并非父類定義的標準遭垛,覆蓋了父類的方法
SichuanPeople scPeople = new SichuanPeople();
people.SayHIStandard(); //并非父類定義的標準,覆蓋了父類的方法
上述代碼操灿,明顯違反了里氏替換原則锯仪,子類覆蓋了父類的非抽象方法,那么當程序所有使用基類的地方牲尺,換上子類的實例卵酪,也將改變原程序的結果幌蚊。根據(jù)里氏替換原則谤碳,我們更新代碼如下:
public abstract class People
{
public void SayHIStandard()
{
Console.WriteLine("普通話:你好");
}
public abstract void SayHICustom();
}
public class HubeiPeople : People
{
public override void SayHICustom()
{
Console.WriteLine("湖北話:你好");
}
}
public class SichuanPeople : People
{
public override void SayHICustom()
{
Console.WriteLine("四川話:你好");
}
}
People hbPeople = new HubeiPeople();
hbPeople.SayHIStandard();
hbPeople.SayHICustom();
People scPeople = new SichuanPeople();
scPeople.SayHIStandard();
scPeople.SayHICustom();
按照里氏替換原則更新代碼過后,不僅可以繼續(xù)使用基類的原有標準SayHIStandard()方法溢豆,還可以調用子類擴展的SayHICustom()方法
使用總結:
- 盡量聲明的時候用父類蜒简,而不是具體的子類
- 子類不要覆蓋父類的方法,如果有需要漩仙,父類的方法應該定義為abstract/virtual搓茬,子類override.