2016-07-29 15 views
0

私は頭の最初のデザインパターンをやっていますが、私はCではなくJavaの例をコーディングしています。私はデコレータパターンをコーディングしましたが、修正方法を理解できないという奇妙なバグがあります。 1行目が期待どおりに動作し、記述が「Dark Roast」ですが、2行目は「Dark Roast、Mocha」ではなく「unknown beverage」に変更されます。この動作を修正するにはどうすればよいですか?C#の継承は期待通りに動作しません

主なプログラム:

beverage = new DarkRoast(); 
beverage = new Mocha(beverage); 
beverage = new Mocha(beverage); 
Console.WriteLine(beverage.Description + " $" + beverage.Cost); 

デコレータコード:

namespace DecoratorPattern 
{ 
    public abstract class Beverage 
    { 
     public abstract double Cost { get; } 

     public string Description { get; set; } = "unknown beverage"; 
    } 

    public class DarkRoast : Beverage 
    { 
     public DarkRoast() 
     { 
      Description = "Dark Roast"; 
     } 

     public override double Cost => .99; 
    } 

    public abstract class CondimentDecorator : Beverage 
    { 
     public abstract string Description { get; } 
    } 

    public class Mocha : CondimentDecorator 
    { 
     Beverage beverage; 

     public Mocha(Beverage beverage) 
     { 
      this.beverage = beverage; 
     } 

     public override string Description 
     { 
      get { return beverage.Description + ", Mocha"; } 
     } 

     public override double Cost => .20 + beverage.Cost; 
    } 
} 
+0

メインプログラムdコンパイルできません。 – Ian

答えて

3

あなたはBeverageクラスのvirtualとしてDescriptionプロパティをマークしていません。したがって、変数beverageBeverageの場合、Descriptionプロパティは常にそこから読み込まれます。値は常にデフォルトの未知数になります。

CondimentDecoratorクラスからabstract宣言を削除し、virtualを基本クラスに追加すると、上書きが機能します。

+0

パーフェクト、ありがとう!私はそれを実装するクラスを強制的に実装を書き出すことをアイデアのため抽象的にしておきました。問題を指摘し説明してくれてありがとう。 – haosmark

+0

'Abstract'プロパティを' CondimentDecorator'クラスから取り除くと 'CondimentDecorator'クラスのポイントは何ですか?もしそうなら、あなたは 'CondimentDecorator'を完全に削除し、' Beverage'から 'Mocha'を継承しても同じ結果を得ることができます。 –

1

あなたは、あなたが期待される結果を取得しますCondimentDecoratorにタイプを変更した場合は、その上に新しいプロパティDescriptionを作り、CondimentDecoratorに元Description財産を隠しています。

これは、あなたが期待している値を印刷する必要があります:

var result = (CondimentDecorator) beverage; 
Console.WriteLine(result.Description); 

あなたはドンを抽象的または仮想となるベースを変更し、この時点で継承したクラスであなたを

public abstract class Beverage 
{ 
    public abstract double Cost { get; } 

    public virtual Description { get; set; } = "unknown beverage"; 
} 

それをオーバーライドする必要があります追加のデコレータクラスが必要です。基本オブジェクトのメソッドをオーバーライドするだけです。

public class Mocha : Beverage 
{ 
    Beverage beverage; 

    public Mocha(Beverage beverage) 
    { 
     this.beverage = beverage; 
    } 

    public override string Description 
    { 
     get { return beverage.Description + ", Mocha"; } 
     set { throw InvalidOperationException("Cannot Set Value of Decorator"); } 
    } 

    public override double Cost => .20 + beverage.Cost; 
} 
関連する問題