Consider I have some abstract Vehicle
class and car, truck, motorcycle abstract classes which derive from Vehicle
. Also imagine that I have to be able to create a fueled based car or electric based car and so on for truck and motorcycle as well. (concrete classes)
Two questions:
1.Consider that I want to fill up energy in a vehicle without knowing what it is, in a polymorphic way. For example if the vehicle is fuel based I want to fill it with fuel and the method should be with 3 parameters:
void FillUpEnergy(EfuelType i_fuelType,int amounOfEnergy, int maxAmountOfEnergy)
but for electricy based vehicle I need almost the same function signture but this time without fuel type of course, for example (2 parameters):
void FillUpEnergy(int amounOfEnergy, int maxAmountOfEnergy)
Can I do a polymorhic FillUpEnergy
method with the above constraints? (different method's signatures)
2.In my implementation all the concrete classes hold a reference for Engine
(another abstract class) which represent a FuelEngine
or ElectricEngine
(other concrete classes I have which derive from Engine). For example I have a concrete class named ElectricCar
which holds a reference for ElectricEngine
.
Is this architecture good enough or are there better ways to implement a garage system?
(In terms of Object oriented design etc..)
You cannot make a polymorphic "push-style" method with different signatures, but you can make a polymorphic "pull-style" method using the well-publicized Visitor Pattern.
The idea is to invert the sequence of interaction, and let the car object decide what to do: Instead of calling FillUpEnergy
and giving the car what you think it needs, call FillUpEnergy
and let the car take what it knows it needs, like this:
interface IEnergyProvider {
void TakeFuel(EfuelType i_fuelType, int amounOfEnergy);
void TakeElectricity(int amounOfEnergy);
}
interface ICar {
void FillUpEnergy(IEnergyProvider provider);
}
Now the signature of your polymorphic method is fixed, but the dispatch of the method takes two legs instead of one:
myCar.FillUpEnergy(myProvider)
myProvider.TakeFuel
or myProvider.TakeElectricity