I'm working through the Head First Design Patterns book and am currently on the Decorator Pattern chapter. Since the book examples are written in Java, I'm adapting the, to C# as I go.
This example simulates a coffee shop ordering system. There is an abstract base class for Beverage
and subclasses for specific beverages (ex: Espresso
). The decorator classes are used to add condiments and drink modifications. There is an abstract class CondimentDecorator
that derives from Beverage
and then subclasses like Mocha
for the individual decorators. Gist with all files: https://gist.github.com/anonymous/67e4fe5fe0477d34b24125f741ad0b3a
My question - in the base Beverage
class, the description string is set to "Unknown beverage". The constructor for a specific drink sets this to the drink name - so if I use:
Beverage espresso = new Espresso();
Console.WriteLine($"{espresso.GetDescription()}");
It responds with "Espresso". Now, when using the decorator, the GetDescription
method is overridden, in the Mocha
class it adds "Mocha" after the beverage's description.
public override string GetDescription()
{
return beverage.GetDescription() + " Mocha";
}
If I use the override
modifier in CondimentDecorator.cs:
public abstract override string GetDescription();
This works as expected. I run:
Beverage espresso = new Espresso();
Console.WriteLine($"{espresso.GetDescription()}"); // Espresso
espresso = new Mocha(espresso);
Console.WriteLine($"{espresso.GetDescription()}"); // Espresso Mocha
However, if I change the modifier to new
in CondimentDecorator.cs like this:
public abstract new string GetDescription();
And run the same code, I get the below results:
Beverage espresso = new Espresso();
Console.WriteLine($"{espresso.GetDescription()}"); // Espresso
espresso = new Mocha(espresso);
Console.WriteLine($"{espresso.GetDescription()}"); // Unknown beverage
I'm a little confused why this happens...since GetDescription
is being called in Mocha like this...
public override string GetDescription()
{
return beverage.GetDescription() + " Mocha";
}
...and beverage is a reference back to the original espresso object, why doesn't the code pick up on the description that was set when Espresso
was instantiated? The way I understand this, new
would hide the original GetDescription
method in the base class while override
would extend that method. I'm not sure why that would effect which description the program reads -- the "unknown beverage" of Mocha
, which gets that value from the Beverage
class it derives from, or the "Espresso" of the beverage object I created that had the description set in the constructor.
I'm sure I'm just misunderstanding something basic about inheritance and how the new and override keywords work, if anyone can shed a little light on this I'd appreciate it!
Thanks!