更改继承类中的抽象方法签名

时间:2011-04-08 15:12:59

标签: c# abstract-class virtual-method abstract-methods

想象一下,我有一个名为Engine的类作为抽象基类。我也有ElectrictEngine和FuelEngine类来源于它。

我想创建一种为引擎加油的方法。 我应该在基类级别上将其作为抽象方法,并将其命名为通用的fasion,例如fillUpEnergy?

问题在于,如果我有一个电动引擎,该方法所采用的参数数量与燃料引擎需要传递的参数数量不同。所以,方法的签名是不同的。

此外,是否有任何智能方法可以为两个引擎使用泛型方法,但是以更具体的名称包装它?例如:对于燃料发动机,“加油”,对于电动发动机,“chargeBattery”?同时隐藏用户的通用方法?

5 个答案:

答案 0 :(得分:6)

在这种情况下,我会定义一个抽象类的通用实现,这样就可以得到这样的结果:

public abstract class EngineBase<T>
{
     public abstract void Refuel(T parameters);
}

然后你的实现看起来像这样:

public class ElectricEngine : EngineBase<ElectricParameters>
{
     public override void Refuel(ElectricParameters parameters) { }
}

或者,您可以定义一个接口,并将特定的实现传递给您的方法:

public abstract class EngineBase
{
     public abstract void Refuel(IRefuelParameters parameters);
}

然后你的实现看起来像这样:

public class ElectricEngine : EngineBase
{
     public override void Refuel(IRefuelParameters parameters)
     {
          if(!(parameters is ElectricParameters))
              throw ApplicationException("Not the right params!");

          ElectricParameters rightParams = parameters as ElectricParameters;
     }
}

答案 1 :(得分:2)

详细了解如何使用这些类。如果你的客户不知道他们正在处理什么样的引擎 - 他们有一个'引擎',那么你必须找出一个可以使用的'加油'签名。另一方面,如果你需要为每种加油方式设置不同的参数,那么你就不能在基类中做任何事情而必须让你的客户知道它是什么类型的引擎并传递正确的算法。

答案 2 :(得分:2)

你可以有一个方法来加油接受一个接口吗?

eg
public void Refuel(IFuel fuel)
{
//do refueling logic
}

您的两种加油方式有哪些参数?

答案 3 :(得分:0)

我将发动机和可加油/可充电部件分开。或者你必须概括有关引擎的所有事情。例如,您可以创建另一个抽象类型(或接口)Charge,并将其传递给recharge方法(在父抽象Engine类中定义)。如果您需要一些代码,请告诉我。

答案 4 :(得分:-1)

抽象类确实不合适,因为Refuel不是将sum类型作为参数的函数(方法)。

这样的事情怎么样?

interface IEngine
{
    void Refuel(FuelingStation station);        
}

class FuelingStation
{
    double Gas;
    double Air;
    double Charge;


    private double GetFuel(ref double fuel, double requested)
    {
        var temp = Math.Max (0, fuel - requested);

        fuel -= temp;

        return temp;
    }


    public double GetGas(double requestedAmount)
    {
        return GetFuel (ref Gas, requestedAmount);

    }

    public double GetAir(double requestedAmount)
    {
        return GetFuel (ref Air, requestedAmount);
    }

    public double GetCharge(double requestedAmount)
    {
        return GetFuel (ref Charge, requestedAmount);
    }
}


class GasEngine : IEngine
{

    double Tank;
    double Capacity;


    public void Refuel(FuelingStation station)
    {
        Tank = station.GetGas (Capacity - Tank);
    }
}


class Electric : IEngine
{

    double Charge;
    double ChargeCapacity;

    double Tank;
    double TankCapacity;



    public void Refuel(FuelingStation station)
    {
        Tank = station.GetGas (TankCapacity - Tank);
        Charge = station.GetCharge (ChargeCapacity - Charge);
    }
}