C# 設計原則-里氏替換原則


  里氏替換原則,全稱Liskov Substitution Principle,英文縮寫LSP。

  一個程序中如果使用的是一個父類,那么該程序一定適用於其子類,而且程序察覺不出父類和子類對象的區別。也就是說在程序中,把父類替換成它的子類,程序的行為沒有任何變化。

  關於里氏替換原則的反例有不少,舉個例子,企鵝不會飛。

  Birds鳥類、Sparrow麻雀類,所有的鳥類都有飛行速度。

public abstract class Birds
{
    //所有鳥類都應該具有飛行速度
    public abstract double FlySpeed();
}

public class Sparrow : Birds
{
    public override double FlySpeed()
    {
        return 12;
    }
}

  此時添加一個Penguin企鵝類,因為企鵝也是鳥類,所以繼承Birds鳥類。

public class Penguin : Birds
{
    public override double FlySpeed()
    {
        return 0;
    }
}

  但因為企鵝不會飛,所以飛行速度設為0,這也算是實現了FlySpeed的方法,運行結果也沒問題。但如果現在有一個方法Fly用來計算一只鳥飛行300米所需要的時間。

public static double Fly(Birds bird)
{
    return 300 / bird.FlySpeed();
}

  當把企鵝Penguin放進去,會出現報錯,因為300/0是不合理的,這就不滿足里氏替換原則。不滿足該原則的原因還是因為Penguin企鵝類沒有完全繼承Birds鳥類,因為企鵝不能飛,實現不了FlySpeed方法。所以要解決這個問題有兩種方案。

  第一種是直接在Fly方法中進行判斷。

public static double Fly(Birds bird)
{
    //如果傳入的類型為企鵝,默認返回0
    if (bird.GetType().Equals(typeof(Penguin)))
    {
        return 0;
    }
    else
    {
        return 300 / bird.FlySpeed();
    }
}

  可這樣就會違反開閉原則,以后如果需要添加新功能,得不斷修改。

  第二種就是Penguin企鵝類不要繼承Birds鳥類,實際上,這里Penguin企鵝就是強行繼承Birds鳥類,雖然現實中企鵝也是鳥,但在代碼中卻不行。

  總結一下里氏替換原則的特點,就是子類可以拓展父類的功能,但是不能改變父類原有的功能。子類可以重寫父類的抽象方法,但不能覆蓋父類的非抽象方法。子類可以增加自己獨有的方法。

 

  


免責聲明!

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



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