11
votes

Modification des signatures de méthode abstraite dans des classes héritées

Imaginez que j'ai une classe appelée moteur comme une classe de base abstraite. J'ai aussi des classes électriciennes et de carburant qui en dérivent.

Je veux créer une méthode de ravitaillement du moteur. Dois-je le faire comme une méthode abstraite sur le niveau de la classe de base et nommez-la dans une fasion générique, telle que Fillupenergy?

Le problème est que si j'ai un moteur électrique, le nombre de paramètres que le procédé prend est différent du nombre de paramètres à transmettre pour un moteur de carburant. Donc, la signature de la méthode est différente.

De plus, existe-t-il un moyen intelligent d'utiliser la méthode générique pour les deux moteurs, mais de l'envelopper dans un nom plus spécifique? Par exemple: pour un moteur de carburant, "ravitaillé", et pour un moteur électrique, "ChargeBattery"? Et en même temps cacher la méthode générique de l'utilisateur?


1 commentaires

Y a-t-il des paramètres communs à faire le plein pour les moteurs électriques et de carburant?


5 Réponses :


2
votes

pense plus à la façon dont vous allez utiliser ces classes. Si votre client ne saura pas quel type de moteur qu'ils traitent - ils ont un «moteur», vous devez ensuite vous cailler une signature «ravitaillement» que Boht peut utiliser. Si d'autre part, vous devez avoir des arguments différents pour chaque type de ravitaillement en carburant, vous ne pouvez rien faire dans la classe de base et avoir à plutôt que votre client savoir quel type de moteur est et transmettez les bons arguments.


0 commentaires

2
votes

Vous pourriez avoir une méthode pour faire le plein qui prend une interface?

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


3 commentaires

Ceci est intelligent. Il sera très intéressant de voir comment Ifuel peut être utilisé de manière générale.


En fonction de quels paramètres les deux autres méthodes le feraient peut être possible. L'interface ifuau pourrait avoir une méthode qui retourne une décimale pour la quantité de carburant augmente par exemple


Oui. Je pensais que si "alimentais" impliquais de renverser ou de ne pas le faire sous la pluie, il est toujours de type moteur-ish.



6
votes

Dans cette situation, je définirais une implémentation générique de votre classe abstraite, de sorte que vous obtenez quelque chose comme ceci: xxx pré>

alors vos implémentations ressemblent à ceci: p>

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 commentaires

Bien que la première solution résout directement le problème avec les paramètres, il rend la classe de base inutile. La solution d'interface est bien meilleure.



0
votes

Je séparerais le moteur et les pièces rechargeables / rechargeables. Ou vous devez généraliser toutes les choses concernant le moteur. Par exemple, vous pouvez créer un autre type abstrait (ou interface) chargé et transmettre ceci sur recharge (qui est défini dans le moteur abstrait parent moteur classe). Faites-moi savoir si vous avez besoin d'un code.


1 commentaires

Saisit simplement quelque chose le long de ces lignes. Je pensais à un charqueProducteur qui prend un argument de powersource.



-1
votes

Une classe abstraite n'est vraiment pas appropriée car le ravitaillement en carburant n'est pas une fonction (méthode) qui prend un type de somme comme paramètre.

Que diriez-vous de quelque chose comme ça? P>

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


0 commentaires