C# 继承不符合我的预期
C# inheritance doesn't behave as I expect it to
我正在研究头脑优先的设计模式,但我正在用 C# 而不是 java 编写示例。我编写了装饰器模式代码,但我遇到了一些我不知道如何修复的奇怪错误。
第 1 行按预期运行,描述为 "Dark Roast",但是第二行将描述更改为 "unknown beverage" 而不是预期的 "Dark Roast, Mocha." 如何解决此问题?
主程序:
beverage = new DarkRoast();
beverage = new Mocha(beverage);
beverage = new Mocha(beverage);
Console.WriteLine(beverage.Description + " $" + beverage.Cost);
装饰器代码:
namespace DecoratorPattern
{
public abstract class Beverage
{
public abstract double Cost { get; }
public string Description { get; set; } = "unknown beverage";
}
public class DarkRoast : Beverage
{
public DarkRoast()
{
Description = "Dark Roast";
}
public override double Cost => .99;
}
public abstract class CondimentDecorator : Beverage
{
public abstract string Description { get; }
}
public class Mocha : CondimentDecorator
{
Beverage beverage;
public Mocha(Beverage beverage)
{
this.beverage = beverage;
}
public override string Description
{
get { return beverage.Description + ", Mocha"; }
}
public override double Cost => .20 + beverage.Cost;
}
}
您没有在 Beverage
class 中将 Description
属性 标记为 virtual
。因此,如果您的变量 beverage
是 Beverage
,则 Description
属性 将始终从那里读取。该值将始终为默认值未知。
只需从 CondimentDecorator
class 中删除 abstract
声明并将 virtual
添加到基础 class,然后您的覆盖将起作用。
您将原来的 Description
属性 隐藏在 CondimentDecorator
中,如果您更改输入 CondimentDecorator
然后你会得到预期的结果。
这应该打印出您期望的值:
var result = (CondimentDecorator) beverage;
Console.WriteLine(result.Description);
您需要将基础更改为抽象或虚拟,并在继承 classes
上覆盖它
public abstract class Beverage
{
public abstract double Cost { get; }
public virtual Description { get; set; } = "unknown beverage";
}
此时你不需要额外的装饰器class只需覆盖基础对象中的方法
public class Mocha : Beverage
{
Beverage beverage;
public Mocha(Beverage beverage)
{
this.beverage = beverage;
}
public override string Description
{
get { return beverage.Description + ", Mocha"; }
set { throw InvalidOperationException("Cannot Set Value of Decorator"); }
}
public override double Cost => .20 + beverage.Cost;
}
我正在研究头脑优先的设计模式,但我正在用 C# 而不是 java 编写示例。我编写了装饰器模式代码,但我遇到了一些我不知道如何修复的奇怪错误。 第 1 行按预期运行,描述为 "Dark Roast",但是第二行将描述更改为 "unknown beverage" 而不是预期的 "Dark Roast, Mocha." 如何解决此问题?
主程序:
beverage = new DarkRoast();
beverage = new Mocha(beverage);
beverage = new Mocha(beverage);
Console.WriteLine(beverage.Description + " $" + beverage.Cost);
装饰器代码:
namespace DecoratorPattern
{
public abstract class Beverage
{
public abstract double Cost { get; }
public string Description { get; set; } = "unknown beverage";
}
public class DarkRoast : Beverage
{
public DarkRoast()
{
Description = "Dark Roast";
}
public override double Cost => .99;
}
public abstract class CondimentDecorator : Beverage
{
public abstract string Description { get; }
}
public class Mocha : CondimentDecorator
{
Beverage beverage;
public Mocha(Beverage beverage)
{
this.beverage = beverage;
}
public override string Description
{
get { return beverage.Description + ", Mocha"; }
}
public override double Cost => .20 + beverage.Cost;
}
}
您没有在 Beverage
class 中将 Description
属性 标记为 virtual
。因此,如果您的变量 beverage
是 Beverage
,则 Description
属性 将始终从那里读取。该值将始终为默认值未知。
只需从 CondimentDecorator
class 中删除 abstract
声明并将 virtual
添加到基础 class,然后您的覆盖将起作用。
您将原来的 Description
属性 隐藏在 CondimentDecorator
中,如果您更改输入 CondimentDecorator
然后你会得到预期的结果。
这应该打印出您期望的值:
var result = (CondimentDecorator) beverage;
Console.WriteLine(result.Description);
您需要将基础更改为抽象或虚拟,并在继承 classes
上覆盖它public abstract class Beverage
{
public abstract double Cost { get; }
public virtual Description { get; set; } = "unknown beverage";
}
此时你不需要额外的装饰器class只需覆盖基础对象中的方法
public class Mocha : Beverage
{
Beverage beverage;
public Mocha(Beverage beverage)
{
this.beverage = beverage;
}
public override string Description
{
get { return beverage.Description + ", Mocha"; }
set { throw InvalidOperationException("Cannot Set Value of Decorator"); }
}
public override double Cost => .20 + beverage.Cost;
}