此代码不起作用,但希望你能得到我在这里想要实现的目标。我有一个Money课程,我从http://www.noticeablydifferent.com/CodeSamples/Money.aspx获取,并将其扩展一点以包括货币转换。
每个项目中实际转换率的实现可能会有所不同,因此我决定将用于检索转换率的实际方法(GetCurrencyConversionRate)移动到派生类中,但ConvertTo方法包含适用于任何实现的代码假设派生类已经覆盖了GetCurrencyConversionRate,那么将它保留在父类中是有意义的吗?所以我要做的是获取一个SubMoney实例,并能够调用.ConvertTo()方法,该方法将使用覆盖的GetCurrencyConversionRate,并返回一个新的SubMoney实例。
问题是,我还没有真正理解多态性和继承的一些概念,所以不太确定我想做的事情甚至可能以我认为的方式实现,因为目前正在发生的是我最终得到一个异常,它使用了基本的GetCurrencyConversionRate方法而不是派生的方法。有些东西告诉我,我需要将ConvertTo方法向下移动到派生类,但这似乎我将在多个实现中复制代码,所以肯定有更好的方法吗?
public class Money
{
public CurrencyConversionRate
{
get
{
return GetCurrencyConversionRate(_regionInfo.ISOCurrencySymbol);
}
}
public static decimal GetCurrencyConversionRate(string isoCurrencySymbol)
{
throw new Exception("Must override this method if you wish to use it.");
}
public Money ConvertTo(string cultureName)
{
// convert to base USD first by dividing current amount by it's exchange rate.
Money someMoney = this;
decimal conversionRate = this.CurrencyConversionRate;
decimal convertedUSDAmount = Money.Divide(someMoney, conversionRate).Amount;
// now convert to new currency
CultureInfo cultureInfo = new CultureInfo(cultureName);
RegionInfo regionInfo = new RegionInfo(cultureInfo.LCID);
conversionRate = GetCurrencyConversionRate(regionInfo.ISOCurrencySymbol);
decimal convertedAmount = convertedUSDAmount * conversionRate;
Money convertedMoney = new Money(convertedAmount, cultureName);
return convertedMoney;
}
}
public class SubMoney
{
public SubMoney(decimal amount, string cultureName) : base(amount, cultureName) {}
public static new decimal GetCurrencyConversionRate(string isoCurrencySymbol)
{
// This would get the conversion rate from some web or database source
decimal result = new Decimal(2);
return result;
}
}
答案 0 :(得分:3)
静态方法只能通过指定声明它的确切类来使用。没有办法让继承参与其中。
使Money
类抽象化,以便必须派生它才能使用。使GetCurrencyConversionRate方法抽象(也自动使其成为虚拟)。让SubMoney
类继承Money
并覆盖GetCurrencyConversionRate
方法:
public abstract class Money {
public abstract decimal GetCurrencyConversionRate(string isoCurrencySymbol);
...
}
public class SubMoney : Money {
public override decimal GetCurrencyConversionRate(string isoCurrencySymbol) {
...
}
}
当方法在Money
类中声明时,它知道它并且可以使用它。您创建实例的实际类是派生类,如SubMoney
,因此始终存在该方法的实现。
答案 1 :(得分:2)
另一种选择是使用Strategy Pattern,从而抽象出转换算法,该算法作为自己的类实现。然后,您可以在运行时切换转换器的实现。这允许您通过使用某种形式的"composition over inheritance"在运行时交换算法来利用dependency injection。
在设计复杂的系统之后,我确实学到了构图优于继承的好处。坦率地说,当你的目标是通过多态增加代码重用时,继承才真正有用。一旦进入复杂类型层次结构,其中继承链超过四层或五层,您最终会遇到横切关注问题(这会导致大量非常相似的代码的复制,这些代码无法在兄弟类型之间共享)。组合允许更简单的设计,易于配置(考虑使用xaml在WPF中设计复杂的表单),测试等等。
无论如何,只是为了给你一些东西来刮你的头。
答案 2 :(得分:1)
您根本没有使用继承/覆盖,而是隐藏了该方法。
public abstract class Money
{
public CurrencyConversionRate
{
get
{
return GetCurrencyConversionRate(_regionInfo.ISOCurrencySymbol);
}
}
public abstract decimal GetCurrencyConversionRate(string isoCurrencySymbol);
public Money ConvertTo(string cultureName)
{
// convert to base USD first by dividing current amount by it's exchange rate.
Money someMoney = this;
decimal conversionRate = this.CurrencyConversionRate;
decimal convertedUSDAmount = Money.Divide(someMoney, conversionRate).Amount;
// now convert to new currency
CultureInfo cultureInfo = new CultureInfo(cultureName);
RegionInfo regionInfo = new RegionInfo(cultureInfo.LCID);
conversionRate = GetCurrencyConversionRate(regionInfo.ISOCurrencySymbol);
decimal convertedAmount = convertedUSDAmount * conversionRate;
Money convertedMoney = new Money(convertedAmount, cultureName);
return convertedMoney;
}
}
public class SubMoney : Money
{
public SubMoney(decimal amount, string cultureName) : base(amount, cultureName) {}
public override decimal GetCurrencyConversionRate(string isoCurrencySymbol)
{
// This would get the conversion rate from some web or database source
decimal result = new Decimal(2);
return result;
}
}
如果将方法声明为抽象方法,则继承类必须覆盖此方法,通过此方法可以强制执行自定义代码。当然,你的SubMoney类必须继承Money才能做到这一点。
答案 3 :(得分:0)
GetCurrencyConversionRate
是静态的。无法覆盖。