【问题标题】:Derived class and override method with derived arguments : how to code it better?派生类和带有派生参数的覆盖方法:如何更好地编码?
【发布时间】: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中进行转换,这样我才能在这些特定的支付方式中使用PilotSailorBoatPlane的特定成员。

我的第一个问题是:连续施放不是难闻的气味吗?

我的第二个问题是:如何进行更优雅的代码设计?我在考虑泛型,并创建一个这样的类:

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


【解决方案1】:

就我个人而言,我会这样做:

public abstract  class PaymentMethod { 
    public decimal GetSalary(Employee employee, Vehicle vehicle) {
        return GetSalaryImpl(employee, vehicle);
    }    
    protected abstract decimal GetSalaryImpl(Employee employee, Vehicle vehicle);
}
public class MarinePaymentMethod : PaymentMethod {
    public decimal GetSalary(Sailor sailor,Boat boat)
    { throw new NotImplementedException(); /* your code here */ }
    protected override decimal GetSalaryImpl(Employee employee, Vehicle vehicle) {
        return GetSalary((Sailor)employee, (Boat)vehicle);
    }
}    
public class AirPaymentMethod : PaymentMethod {
    public decimal GetSalary(Pilot pilot, Plane plane)
    { throw new NotImplementedException(); /* your code here */ }
    protected override decimal GetSalaryImpl(Employee employee, Vehicle vehicle) {
        return GetSalary((Pilot)employee, (Plane)vehicle);
    }
}
public class Employee {}
public class Vehicle{}
public class Sailor : Employee{}
public class Pilot : Employee{}
public class Boat: Vehicle{}
public class Plane: Vehicle{}

这适用于多态性和重载方法 - 尽管采用 Employee 的方法需要特定的类型员工是不寻常的。

【讨论】:

  • 在我的代码中,我有一个使用基类的“算法”。在这段代码中,我想使用在派生类中被覆盖的模板方法和派生参数,因为我需要在被覆盖的方法中实现派生。看来您的建议可以完成这项工作。这是一种优化的演员阵容,因为演员阵容只有一次!
  • “采用 Employee 的方法需要特定类型的员工是不寻常的。”该方法采用员工,因为它是一种抽象方法,用于所有员工通用的通用算法。但是,覆盖的方法执行需要特定员工的工作。那是我的问题!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-21
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 2010-11-22
  • 2013-09-11
  • 1970-01-01
相关资源
最近更新 更多