2011-04-08 62 views
9

想象一下,我有一个名为Engine的类作为抽象基类。我也有从它派生的ElectrictEngine和FuelEngine类。更改继承类中的抽象方法签名

我想创建一个加油引擎的方法。 我是否应该将它作为基类级别上的抽象方法进行处理,并将其命名为通用方式,例如fillUpEnergy?

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

此外,是否有任何智能的方法来使用这两种引擎的通用方法,但用更具体的名称来包装它?例如:对于燃油引擎,“加油”,对于电动引擎,“充电电池”?同时从用户隐藏通用方法?

+0

是否有任何常见的参数为电动和燃油发动机加油? – tomasmcguinness 2011-04-08 15:17:47

回答

2

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

2

你可以有一个方法来加油,需要一个接口?

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

您的两种加油需要哪些参数?

+0

这很聪明。了解IFuel如何一般使用将会非常有趣。 – n8wrl 2011-04-08 15:17:45

+0

取决于其他两种方法将采用它的参数。IFuel接口可以有一个方法,返回一个小数的燃油增量,例如 – WraithNath 2011-04-08 15:19:05

+0

是的。我在想,如果'加油'涉及不下雨或不下雨,它仍然是引擎式的。 – n8wrl 2011-04-08 16:00:29

5

在这种情况下,我会定义一个通用的实现你的抽象类的,这样你得到的东西是这样的:

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; 
    } 
} 
+0

尽管第一种解决方案直接解决了参数问题,但它使基类无用。接口解决方案好得多。 – siride 2011-04-08 15:37:48

0

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

+0

只是沿着这些线打字。我正在考虑采用PowerSource参数的TorqueProducer。 – 2011-04-08 15:27:30

-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); 
    } 
}