2011-04-08 28 views
9

Imagine que tengo una clase llamada Engine como clase base abstracta. También tengo clases de ElectrictEngine y FuelEngine que derivan de ella.Cambiar las firmas de métodos abstractos en las clases heredadas

Quiero crear un método para reabastecer el motor. ¿Debería hacerlo como un método abstracto en el nivel de clase base y nombrarlo en un fasion genérico, como fillUpEnergy?

El problema es que si tengo un motor eléctrico, el número de parámetros que toma el método es diferente del número de parámetros que deben pasarse para un motor de combustible. Entonces, la firma del método es diferente.

Además, ¿hay alguna manera inteligente de utilizar el método genérico para ambos motores pero para envolverlo en un nombre más específico? Por ejemplo: para un motor de combustible, "repostar", y para un motor eléctrico, "cargar batería"? ¿Y al mismo tiempo ocultar el método genérico del usuario?

+0

¿Hay algún parámetro común para Recargar combustible para los motores eléctricos y de combustible? – tomasmcguinness

Respuesta

2

Piense más sobre cómo va a utilizar estas clases. Si su cliente no sabe qué tipo de motor están tratando, tienen un 'motor', entonces tiene que calcular una firma de 'reabastecimiento' que pueda usar. si, por otro lado, TIENE que tener argumentos diferentes para cada tipo de reabastecimiento de combustible, entonces no puede hacer nada en la clase base y en su lugar debe hacer que su cliente sepa qué tipo de motor es y pasar las args correctas.

2

¿Podría tener un método para reabastecer de combustible que lleva una interfaz?

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

¿Qué parámetros requieren sus dos tipos de repostaje?

+0

Esto es inteligente. Será muy interesante ver cómo IFuel se puede usar genéricamente. – n8wrl

+0

dependiendo de qué parámetros tomarían los otros dos métodos podría ser posible.La interfaz de IFuel podría tener un método que arroje un decimal para la cantidad de combustible aumentada, por ejemplo, – WraithNath

+0

Sí. Estaba pensando si 'cargar combustible' involucrado no derramar nada o no hacerlo en la lluvia sigue siendo un tipo de motor. – n8wrl

5

En esta situación, yo definiría una implementación genérica de su clase abstracta, de manera que se obtiene algo como esto:

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

A continuación, sus implementaciones de este aspecto:

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

Alternativamente, puede definir una interfaz y pasar una implementación específica a sus métodos:

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

A continuación, sus implementaciones de este aspecto:

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

Si bien la primera solución resuelve directamente el problema con los parámetros, hace que la clase base sea inútil. La solución de interfaz es mucho mejor. – siride

0

que separaría el motor y las partes recargables de reabastecimiento-poder /. O tienes que generalizar todas las cosas relacionadas con el motor. Por ejemplo, puede crear otro tipo abstracto (o interfaz) Charge, y pasarlo al método recharge (que se define en la clase primaria abstracta Engine). Avísame si necesitas un código.

+0

Estaba escribiendo algo en ese sentido. Estaba pensando en un TorqueProducer que toma un argumento de PowerSource. –

-1

Una clase abstracta realmente no es apropiada porque Refuel no es una función (método) que toma un tipo de suma como un parámetro.

¿Qué tal algo como esto?

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