最近看了大话设计模式书中的装饰者模式,然后用C#照着写了一遍,发现运行出来的结果和书上不一样,然后又用Java写了一遍 和书上一样,同样的代码,不同的编译器与运行环境,Java和.NET 下面贴上代码
首先是Java实现
Beverage(饮料抽象类)
CondimentDecorator(调料抽象类,继承Beverage)
Latte(拿铁饮料,继承Beverage)
Mocha(摩卡调料,继承CondimentDecorator)
public abstract class Beverage {
public String description = "Unkonw";
public String getDescription(){
return description;
}
public abstract double cost();
}
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
public class Latte extends Beverage {
public Latte(){
description = "Latte Coffee";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 21.05;
}
}
public class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription() + ", Mocha Condiment";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return .99 + beverage.cost();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Beverage beverage1 = new Latte();
beverage1 = new Mocha(beverage1);
System.out.println("小明点了:"+beverage1.getDescription()+"咖啡,花了:"+beverage1.cost()+" RMB");
}
运行结果
下面看下C#中的实现
Beverage(饮料抽象类)
CondimentDecorator(调料抽象类,继承Beverage)
Espresso(浓咖啡,继承Beverage)
SoyMilk(豆奶调料,继承CondimentDecorator)
public abstract class Beverage
{
public string description = "Unknow";
public string getDescription()
{
return description;
}
public abstract double cost();
}
public abstract class CondimentDecorator:Beverage
{
public abstract string getDescription();
}
public class Espresso :Beverage
{
public Espresso()
{
description = "Espresso Coffee(浓咖啡)";
}
public override double cost()
{
return 19.00;
}
}
public class SoyMilk:CondimentDecorator
{
private Beverage beverage;
public SoyMilk(Beverage bev)
{
this.beverage = bev;
}
public override string getDescription()
{
return beverage.getDescription() + "SoyMilk(豆奶调料)";
}
public override double cost()
{
return 1.25 + beverage.cost();
}
}
public static void Main(string[] args)
{
Beverage espresso = new Espresso();
espresso = new SoyMilk(espresso);
Console.WriteLine("小张点了一杯:" + espresso.getDescription() + " 咖啡, 价格是:" + espresso.cost() + " RMB");
Console.ReadLine();
}
可以看出,除了饮料名称之外,代码都是一样的,下面是运行结果
和上面Java的结果对比确实不一样,下面把C#中的Beverage和CondimentDecorator改一下
把Beverage的getDescription方法写成虚方法
public virtual string getDescription()
{
return description;
}
然后把CondimentDecorator的加上override
public abstract override string getDescription();
下面是运行结果
这样就正常了,是不是很神奇
来分析一下Java中执行步骤
Beverage beverage1 = new Latte(); //父类实例化Latte
beverage1 = new Mocha(beverage1); //Latte作为参数实例化Mocha
//beverage1getDescription首先调用Mocha中的getDescription方法,然后再调用Latte里面的getDescription方法(隐式继承了父类)
beverage1.getDescription();
一直搞不懂C#中这样到底是怎么执行的,有了解的请给我留言,万分感谢
原文地址:http://blog.csdn.net/xiaoyiyz/article/details/46674385