我有这样一个抽象类:
public abstract class Beverage
{
public string description = "Unkown Beverage"; public string getDescription()
{
return this.description;
} public abstract double cost();
}
一个装饰类:
public abstract class CondimentDecorator:Beverage
{
public abstract string getDescription();
}
一个Beverage的子类:
public class HouseBlend:Beverage
{
public HouseBlend()
{
description = "House Blend Coffee";
} public override double cost()
{
return 0.89;
}
}
一个CondimentDecorator的子类
public class Mocha:CondimentDecorator
{
Beverage bev;
public Mocha(Beverage bever)
{
this.bev = bever;
} public override string getDescription()
{
return this.bev.getDescription()+",Mocha";
}
public override double cost()
{
return this.bev.cost()+0.20;
}
}
运行文件:
static void Main(string[] args)
{
Beverage bev2 = new HouseBlend();
bev2 = new Mocha(bev2);
Console.WriteLine(bev2.getDescription()+" $"+bev2.cost());
Console.ReadLine();
}
运行结果应该是:House Blend Coffee,Mocha $1.09
现在显示为:Unkown Beverage $1.09
这个getDescription没有起装饰作用,请问这是怎么回事???
谢谢!!!

解决方案 »

  1.   

    “CondimentDecorator.getDescription()”隐藏了继承的成“Beverage.getDes
    cription()”。如果是有意隐藏,请使用关键字 new。
      

  2.   

    使用关键字 new,结果也是一样!
      

  3.   

    如果你的这段代码是设计模式上的,我只能说设计很烂,把设计的很多大忌都包括了。先回答你的问题,再说为什么设计很烂、恨恶心。Condiment....那个类并没有覆盖GetDesc...方法,而是自己提供了一个,这样他就有两个GetDesc....方法,一个是从父类接口继承来的,一个是自己的。Mocha是从它继承的不假,但是dev2声明的是Beve....类型,因此dev2.Getde....方法应该执行的是从Beve....继承来的那个方法的功能,而不是从Condi....类继承来的那个没有从Beve...继承而独立定义的但是同名的方法。因此,dev2.GetDesc...方法并不是像Mocha里定义那样调用实例化时传给他的Beve...类型的参数的GetDesc....方法,而应该是直接执行Beve...类的GetDesc...方法,也就是return this.decription。而在new Mocha(dev2)的时候,首先执行了this.description初始化的值就是"Unknown....",然后执行了this.bev=...这一句。看出为什么很烂,很恶心了吧?竟然有人把它当作模式?!!以丑为美的做法。
    Condim....类在Beve....类之外,定义了一个同名的方法,这是第一丑。将来这种混乱要害死人的。
    Mocha形式上是从Beve...类继承的,同时又以一个Beve....类型的对象作为自己的属性,并且将所有操作委派为(偷换为)参数的操作,这是第二丑。两丑恰好组合在一起形成关联关系,产生了更大的丑。
    设计模式是在面向对象设计早期,一些“大师”想用面向对象设计技术迎合传统结构化设计(他们认为继承会毁掉体系结构,需要尽量用组合来替代继承)的习惯,而开发出来的。其大多数内容以繁琐为美,以丑为美。
      

  4.   

    这是《深入浅出设计模式(影印版)》中decorator章的代码,它用来解决大量相似类的动态生成问题,原来的代码是java的,我改写成C#的就出现这个问题,其实我什么主要内容也没改,只是把extends,implements改为: 。
      

  5.   

    这个例子的源意是这样的:
    在饮料店中有很多种饮料(Beverage),比如咖啡(HouseBlend)...,又有很多种可以放入咖啡的调料(Condiment),这样就产生很多种组合,比如放奶的咖啡价钱是0.1+1,放糖的咖啡是0.05+1,而且放入的量还可能是几份,如果你为每一种组合生成一个类那么就有很多个类,这样到最后你就没法用了。通过装饰模式,你只需定义咖啡,然后定义一个装饰类,所有调料通过装饰类来继承:
    Beverage bev3 = new HouseBlend(); // 定义一直咖啡
    bev3 = new Soy(bev3);   // 放入一种调料
    bev3 = new Soy(bev3);   // 再放入同意的调料
    bev3 = new Whip(bev3);  // 放入其他调料
    Console.WriteLine(bev3.getDescription()+" $"+bev3.cost()); // 得到这种咖啡全面的描述和最后的价格我刚开始接触设计模式,以前只是根据自己的了解来重构代码,现在通过学习设计模式发现代码还可以这样写,它为我的工作和学习打开了令一扇门。sp1234谈的是一番过来人的感受,我很羡慕,希望我有一天也能达到他的高度!
      

  6.   

    装饰模式其实很好的,可以动态地增加或减少被装饰类的功能.
    上面只须改为
    public abstract class Beverage
    {
    public string description = "Unkown Beverage";public virtual string getDescription()
    {
    return this.description;
    }public abstract double cost();
    }

    public abstract class CondimentDecorator:Beverage
    {
    public override string getDescription()
    {
       return null;
    }
    }
    就行了???
      

  7.   

    sp1234(SmartNavigation变为obsolete,asp.net进取心气数尽了?)看起来很厉害,能否介绍一下从业经历,何以达到这样的修行?
      

  8.   

    看着面熟,应该是Head First Design Patterns里Java例子的翻版,想看.NET例子版本的话,看http://codebetter.com/blogs/darrell.norton/archive/2005/05/18/63332.aspx
      

  9.   

    老大来了,荣幸、荣幸!!!的确是Head First Design Patterns中的java例子!