違反 LSP Liskov Substitution Principle 里氏替換原則
有很多人對於 LSP Liskov Substitution Principle 里氏替換原則 所講述的內容,看得很模糊,有些時候是學習者對於物件導向程式設計觀念不慎清楚、開發經歷中,也甚少經常設計類別繼承的程式碼,不過,也有人說,我都有設計類別繼承,要是我,才不會有這樣的問題;可是,這是個原則,講的是當您遵從這個原則之後,就不會設計出有行為異常的子類別,有些時候,您也可能需要維護別人開發的舊專案,這個專案也許不知道經過幾個人來維護過了,往往有需求變更的時候,為了客戶時效要求,手頭上有很多專案要開發,就直接繼承類別,產生新的子類別來設計出滿足變更需求的程式,當然,經過一段時間之後,這個專案上就會產生違反 LSP 的問題;不過,說實在的,若這個專案從頭到尾都是您自己開發,也是有可能產生違反 LSP 的問題。一旦程式碼出現違反 LSP 的原則,就會產生出許多意想不到的問題,而這些問題,很多時候是在設計與除錯時候,無法立即發現到的 (更多關於 LSP 的介紹,網路上已經有海量的文章,請各位自行去搜尋、研究)
現在,讓我們來看看底下的範例,您能夠看出它存在著甚麼問題嗎?
另外,他是否有遵從 LSP 原則嗎?
不論答案是肯定或者是否定,請您要提出的論述觀點,這樣,才能夠知道,您是否真正明瞭甚麼是 LSP Liskov Substitution Principle 里氏替換原則
class 鳥
{
public virtual void 飛() { Console.WriteLine("鳥在飛"); }
public virtual void 吃() { Console.WriteLine("鳥在吃"); }
}
class 老鷹 : 鳥
{
public override void 飛() { Console.WriteLine("老鷹在飛"); }
public override void 吃() { Console.WriteLine("老鷹在吃"); }
}
class 鴕鳥 : 鳥
{
public override void 飛() { throw new NotSupportedException("鴕鳥不能飛"); }
public override void 吃() { Console.WriteLine("老鷹在吃"); }
}
底下是使用上面類別的範例程式碼
class Program
{
static void Main(string[] args)
{
List<鳥> birds = new List<鳥>();
birds.Add(new 鳥());
birds.Add(new 老鷹());
birds.Add(new 鴕鳥());
BirdsFly(birds);
}
static void BirdsFly(List<鳥> birdList)
{
foreach (var item in birdList)
{
item.飛();
}
}
}
沒有留言:
張貼留言