java設計原則之里氏替換原則

What java

  Liskov Substitution Principle(LSP),任何父類出現的地方,子類必定能夠出現。ide

  Whycode

  LSP是OCP原則的規範。OCP原則的關鍵的是抽象,而繼承關係又是抽象的一種具體表現。繼承

  Howip

  當子類不能完整的實現父類父類的方法,那麼建議斷開父子關係,採用依賴,聚合,組合等關係替代繼承。下面是一個經典例子,鴕鳥不是鳥ci

  抽象鳥類,這裏咱們認爲鳥類都會飛,抽象方法是獲取飛行速度string

abstract class Bird : IFLy
    {
        Wing[] wings;
        public Bird()
        {
            wings = new Wing[2];
        }

        protected abstract double GetFlightSpeed();

        //飛行一段距離所需時間
        public double Fly(double distance)
        {
            return distance / GetFlightSpeed();
        }
    }

燕子類,飛行速度是120it

class Swallow : Bird
    {
        protected override double GetFlightSpeed()
        {
            return 120d;
        }
    }

鴕鳥類,鴕鳥不會飛,那麼飛行速度是0io

class Ostrich : Bird
    {
        protected override double GetFlightSpeed()
        {
            return 0d;
        }
    }

客戶端調用class

class Program
    {
        static void Main(string[] args)
        {
            Bird bird = new Swallow();
            Double distance = 100;
            string time = bird.Fly(distance).ToString();
            Console.WriteLine(time);
            Console.ReadLine();
        }
    }

這樣看是沒有問題的,可是當換成下列這樣的狀況

class Program
    {
        static void Main(string[] args)
        {
            Bird bird = new Ostrich();
            Double distance = 100;
            string time = bird.Fly(distance).ToString();
            Console.WriteLine(time);
            Console.ReadLine();
        }
    }

這樣就是違反了LSP,由於鴕鳥並不能實現全部的鳥類功能,由於它不會飛,因此沒有飛行速度,那麼未來客戶端調用的使用,當成一種鳥類飛行,就會形成不可預知的錯誤。

  爲何會形成這樣的狀況,實際上是由於抽象封裝的時候出現了問題,從生態學上來講有翅膀、有羽毛等特色的就是鳥,那麼會飛的鳥應該是鳥類的一個分支,因此咱們應該從新劃分類的職責範圍

abstract class Bird
    {
        Wing[] wings;
        public Bird()
        {
            wings = new Wing[2];
        }
    }
abstract class FlyBird : Bird, IFLy
    {
        protected abstract double GetFlightSpeed();

        public double Fly(double distance)
        {
            return distance / GetFlightSpeed();
        }
    }
class Program
    {
        static void Main(string[] args)
        {
            IFLy flyBird = new Swallow();
            Double distance = 100;
            string time = flyBird.Fly(distance).ToString();
            Console.WriteLine(time);
            Console.ReadLine();
        }
    }
相關文章
相關標籤/搜索