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(); } }