【发布时间】:2014-12-16 10:46:53
【问题描述】:
我有一个关于派生、多态性和方法签名的问题
我有课
public abstract class PaymentMethod
{
public abstract float GetSalary (Employee employee,Vehicule vehicule)
}
还有另外两个
public class MarinePaymentMethod : PayementMethod
{
public override float GetSalary (Sailor sailor,Boat boat)
}
public class AirPaymentMethod : PayementMethod
{
public override float GetSalary (Pilot pilot,Plane plane)
}
我们还假设:
public class Sailor : Employee{}
public class Pilot : Employee{}
public class Boat: Vehicule{}
public class Plane: Vehicule{}
所以,“问题”是这段代码无法编译,因为签名不一样。
我强制保留基本签名 GetSalary(Employee employee, Vehicule vehicule)
然后我必须在Derived Payment Method中进行转换,这样我才能在这些特定的支付方式中使用Pilot、Sailor、Boat、Plane的特定成员。
我的第一个问题是:连续施放不是难闻的气味吗?
我的第二个问题是:如何进行更优雅的代码设计?我在考虑泛型,并创建一个这样的类:
public abstract class PaymentMethod<T, U> where T: Employee where U: Vehicule
但是在我的代码中,我意识到我必须在使用支付方法类的几乎所有地方都使用泛型,这会使代码变得繁重。还有其他解决方案吗?
非常感谢
【问题讨论】:
-
不要使用浮点数作为货币。货币是十进制的,所以使用十进制类型来表示它而不是二进制浮点数。
-
为什么要强制保留基本签名?在我看来,您真的不应该尝试覆盖派生类中的方法。如果派生类中的 getSalary 方法需要利用某些基本 GetSalary 功能,只需将基上的方法公开为受保护而不是使其抽象。
-
是的,这是一种难闻的气味 - 基本上,您的每个
PaymentMethod实现只能在 一些 情况下使用,即人们希望使用PaymentMethod。是的,您的替代方法听起来很合理。不清楚您所说的“它使代码繁重”是什么意思。 -
好吧,问问自己
GetSalary(new Sailor(), new Plane())是否有意义。如果不是那么,可能是设计有问题(是否使用泛型并不重要)。 受保护的基类方法和派生类中的几个公共特化...可能(例如here)。您是否需要调用基本非专业方法?您是否需要调用派生的专用方法?最后不要忘记你不是重写基类方法而是重载它们。保留它(如果你需要这样的方法。 -
你能贴一个调用代码的sn-p吗?我很确定有一个更简洁的解决方案,可能会将 GetSalary 方法移至 Sailor/Pilot 类。如果您引入 PaymentMethod 类只是为了封装通用算法,那么可以通过协作者来解决。在不知道你怎么称呼它的情况下很难确定。
标签: c# generics polymorphism overriding abstract-class