亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

違反 Liskov 替換原則的策略模式

違反 Liskov 替換原則的策略模式

慕村9548890 2021-09-15 14:22:52
我正在實施策略模式來實現不同類型鴨子的行為。這是代碼:public interface IFlybehaviour {  public void fly();}public class GeneralFlybehaviour{  public void fly()  {    Console.WriteLine("I can fly as a duck");  }}public abstract class Duck{  IFlybehaviour flybehaviour;  Duck()  {  }  public void PerformFly()  {   flybehaviour.fly();  }}public class SimpleDuck : Duck{  public SimpleDuck(IFlybehaviour flybehaviour)  {    flybehaviour = new GeneralFlybehaviour();  }}In the main methodvoid main(){  Duck d = new SimpleDuck();  d.PerformFly();}這符合“開放封閉原則”和“ Liskov 替代原則”,我可以在其中創建 50 種不同類型的鴨子,例如SimpleDuck,FlyingDuck等等?,F在我需要一個ComplicatedDuck具有特殊能力的類來實現其弟子的愿望讓我們說://public class ComplicatedDuck extends Duck (Java)    public class ComplicatedDuck : Duck     {      public ComplicatedDuck(IFlybehaviour flybehaviour)      {        flybehaviour = new GeneralFlybehaviour();      }     public void GrantWishes()     {        Console.WriteLine("Wish Granted")     }    }通過此更改,我們知道它違反了“Liskov 替換原則”,即該子類不會完全替換其基類。假設如果我在“抽象類 Duck”中再添加一個函數,那么所有繼承的成員至少需要提供一個實現,說明“我不授予特殊的愿望”。在這種情況下,這是更好的解決方案,在 ComplicatedDuck 類中添加一個方法或擴展 BaseClass注意:同樣的概念適用于 Java 也只是用“implements”關鍵字替換“:”。
查看完整描述

3 回答

?
MM們

TA貢獻1886條經驗 獲得超2個贊

這是組合與繼承的經典案例。

您創建了一輛基類汽車……所有可預見的汽車都有門和輪子,以及某種描述的引擎……繼承運行良好……但收音機是可選的。你做什么工作。那么你使用組合。

你創建了一個名為 IRadio 的接口,并且對于每輛有收音機的汽車,你用 IRadio 裝飾它(假設這是 C#),這就是組合。檢查汽車是否有收音機很容易,只需檢查 IRadio,在任何有 RadioEnabled 的汽車上都可以輕松打開收音機。

帶回家的部分。在不需要它們的派生類上強制使用方法很麻煩。然而,在可以推導的情況下將所有東西都組合起來也是一種浪費。你只需要在邏輯上畫線


查看完整回答
反對 回復 2021-09-15
?
隔江千里

TA貢獻1906條經驗 獲得超10個贊

策略模式是關于具有不同的實現,IFlyBehavior而不是關于繼承Duck.

您的代碼的一個問題是您的Duck基類中有一個從未使用過的私有字段。它只能被 Duck 使用,因此所有繼承類型都無法訪問它。如果你PerformFly()會得到一個 NullReferenceException - 總是。如果你想繼承Duck可能想在 Duck 的構造函數中采用 IFlyBehavior。

flybehaviour = new GeneralFlybehaviour();

有點違背了擁有策略模式的目的,因為它會強制對其進行特定的實現。我想如果你想使用特定的IFlyBehavior實現,而不是從 Duck 繼承,你會使用組合


查看完整回答
反對 回復 2021-09-15
?
拉莫斯之舞

TA貢獻1820條經驗 獲得超10個贊

我認為您只是錯過了從 Duck 類繼承 ComplicatedDuck。它必須像 - ComplicatedDuck : Duck

  • 您可以將現有方法 - public void GrantWishes() 移動到抽象類 Duck。

  • 使用空定義使其成為虛擬。

  • 在 ComplicatedDuck 類中,根據需要覆蓋行為。

  • 在 SimpleDuck 類中什么都不做。

這樣就不會違反替代原則。


查看完整回答
反對 回復 2021-09-15
  • 3 回答
  • 0 關注
  • 188 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號