我在看 this维基百科文章,无法理解它到底是如何工作的。有点沮丧不能仅仅通过查看代码来理解代码,我决定将代码移植到 c#(我是 .net,对不起大家 :))。只需要做一些小的修改(继承和扩展,super 的基础等)并运行应用程序。令我惊讶的是,我得到了以下输出:
Cost: 1 Ingredient: Coffee
Cost: 1 Ingredient: Coffee
Cost: 1 Ingredient: Coffee
Cost: 1 Ingredient: Coffee
只是好奇,任何 Java 开发人员都可以告诉我这里有什么不同以及为什么维基百科示例有效(当然,如果它确实像他们所说的那样有效)。
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Coffee sampleCoffee = new SimpleCoffee();
Console.WriteLine("Cost: " + sampleCoffee.getCost() + " Ingredient: " + sampleCoffee.getIngredient());
sampleCoffee = new Milk(sampleCoffee);
Console.WriteLine("Cost: " + sampleCoffee.getCost() + " Ingredient: " + sampleCoffee.getIngredient());
sampleCoffee = new Sprinkles(sampleCoffee);
Console.WriteLine("Cost: " + sampleCoffee.getCost() + " Ingredient: " + sampleCoffee.getIngredient());
sampleCoffee = new Whip(sampleCoffee);
Console.WriteLine("Cost: " + sampleCoffee.getCost() + " Ingredient: " + sampleCoffee.getIngredient());
Console.ReadKey();
}
}
//The Coffee Interface defines the functionality of Coffee implemented by decorator
public interface Coffee
{
double getCost(); // returns the cost of coffee
String getIngredient(); //returns the ingredients mixed with coffee
}
//implementation of simple coffee without any extra ingredients
public class SimpleCoffee : Coffee
{
double cost;
String ingredient;
public SimpleCoffee()
{
cost = 1;
ingredient = "Coffee";
}
public double getCost()
{
return cost;
}
public String getIngredient()
{
return ingredient;
}
}
//abstract decorator class - note that it implements coffee interface
abstract public class CoffeeDecorator : Coffee
{
protected Coffee decoratedCoffee;
protected String ingredientSeparator;
public CoffeeDecorator(Coffee decoratedCoffee)
{
this.decoratedCoffee = decoratedCoffee;
ingredientSeparator = ", ";
}
public CoffeeDecorator()
{
}
public double getCost() //note it implements the getCost function defined in interface Coffee
{
return decoratedCoffee.getCost();
}
public String getIngredient()
{
return decoratedCoffee.getIngredient();
}
}
//Decorator Milk that mixes milk with coffee
//note it extends CoffeeDecorator
public class Milk : CoffeeDecorator
{
double cost;
String ingredient;
public Milk(Coffee decoratedCoffee) : base(decoratedCoffee)
{
cost = 0.5;
ingredient = "Milk";
}
public double getCost()
{
return base.getCost() + cost;
}
public String getIngredient()
{
return base.getIngredient() + base.ingredientSeparator + ingredient;
}
}
//Decorator Whip that mixes whip with coffee
//note it extends CoffeeDecorator
public class Whip : CoffeeDecorator
{
double cost;
String ingredient;
public Whip(Coffee decoratedCoffee)
: base(decoratedCoffee)
{
cost = 0.7;
ingredient = "Whip";
}
public double getCost()
{
return base.getCost() + cost;
}
public String getIngredient()
{
return base.getIngredient() + base.ingredientSeparator + ingredient;
}
}
//Decorator Sprinkles that mixes sprinkles with coffee
//note it extends CoffeeDecorator
public class Sprinkles : CoffeeDecorator
{
double cost;
String ingredient;
public Sprinkles(Coffee decoratedCoffee) : base(decoratedCoffee)
{
cost = 0.2;
ingredient = "Sprinkles";
}
public double getCost()
{
return base.getCost() + cost;
}
public String getIngredient()
{
return base.getIngredient() + base.ingredientSeparator + ingredient;
}
}
}
最佳答案
是的 - 默认情况下方法在 Java 中是虚拟的,但在 C# 中不是。
您应该在编译代码时收到警告,谈论“new”修饰符。那应该给了你一个线索。目前,您的 Milk
(等)方法正在隐藏或隐藏那些在 CoffeeDecorator
中的方法 - 它们没有被多态调用.
您需要使用 virtual
修饰符使 CoffeeDecorator
方法成为虚拟方法,然后在 Milk
(等)中显式覆盖它们override
修饰符。
// In CoffeeDecorator
public virtual double getCost()
{
return decoratedCoffee.getCost();
}
// In Milk
public override double getCost()
{
return base.getCost() + cost;
}
关于c# - 装饰模式问题C#/java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4333462/