为何始终获取C#抽象类字符串?装饰器模式调用异常排查
问题原因分析
你的代码问题出在装饰器基类CondimentDecorator的方法定义错误:
- 基类
Beverage中的getDescription()是public方法,但CondimentDecorator没有重写这个方法,反而重新定义了一个protected abstract的同名方法。 - 当你通过
Beverage类型的引用(d变量)调用getDescription()时,程序只会执行Beverage类的默认实现,返回"Unknown Beverage",不会触发Mocha中编写的装饰逻辑。 - 同时,Mocha类中实现的是
protected override的getDescription(),无法被外部代码直接调用,进一步导致装饰逻辑失效。
修复后的代码
以下是修正后的完整代码:
// 测试代码 Beverage e = new Espresso(); Console.WriteLine(e.getDescription() + " $" + e.cost()); Beverage d = new DarkRoast(); d = new Mocha(d); Console.WriteLine(d.getDescription() + " $" + d.cost()); // 抽象基类 public abstract class Beverage { protected string description = "Unknown Beverage"; public virtual string getDescription() // 改为virtual,允许子类重写 { return description; } public abstract double cost(); } // 装饰器基类 public abstract class CondimentDecorator : Beverage { public Beverage beverage; // 重写基类的public方法,声明为抽象让子类实现 public abstract override string getDescription(); } // 具体饮品 public class Espresso : Beverage { public Espresso() { description = "Espresso"; } public override double cost() { return 1.99; } } public class DarkRoast : Beverage { public DarkRoast() { description = "The Darkest of Roasts"; } public override double cost() { return .99; } } // 具体装饰器 public class Mocha : CondimentDecorator { public Mocha(Beverage beverage) { this.beverage = beverage; } public override double cost() { return beverage.cost() + .20; } // 改为public override,实现装饰器的描述逻辑 public override string getDescription() { return beverage.getDescription() + ", Mocha"; } }
关键修复点
- 将
Beverage类中的getDescription()改为public virtual,允许子类重写。 - 修改
CondimentDecorator类,将protected abstract string getDescription()替换为public abstract override string getDescription(),确保它重写基类方法,强制子类实现装饰后的描述逻辑。 - 将
Mocha类中的protected override string getDescription()改为public override string getDescription(),使其能被外部通过Beverage引用正确调用。
修复后运行代码,会得到预期输出:
Espresso $1.99 The Darkest of Roasts, Mocha $1.19
内容的提问来源于stack exchange,提问作者Oswald
相关产品推荐
相关产品推荐

