2011-04-08 86 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); 
    } 
}