Reputation: 11
in my work im trying to write a garage system management. theres an abstract class vehicle(it has list of wheels(also a class), an engine, and more unimportent parameters), car is derived of vihecle, (also motorcycle) and car work on fuel, car work on electricity are derived of car.(same to motorcycle).
each car has other engine, therefor in the constructor im using i_Engine(which inside Engine) = new WorkedOnFuel(WorkedOnFuel.eFuelType.Soler, 0, 115);
each of WorkedOnFuel/WorkedOnElectricity class has its own method to add energy to its own engine(fuel needs fuel type and fload of liters, electricity needs float hours to add).
is there any possibility to cast and use this methods?
Note: i cant use Interface!
im adding here the codes by classes:
public abstract class Vehicle
{
private string m_ModelName;
private string m_LicenseNumber;
private List<Wheel> m_Wheels;
private Engine m_Engine;
public Vehicle(string i_ModelName, string i_LicenseNumber)
{
m_ModelName = i_ModelName;
m_LicenseNumber = i_LicenseNumber;
m_Wheels = new List<Wheel>();
}
public Engine i_Engine
{
get
{
return m_Engine;
}
set
{
m_Engine = value;
}
}
public List<Wheel> i_Wheels
{
get
{
return m_Wheels;
}
set
{
m_Wheels = value;
}
}
public string i_ModelName
{
get
{
return m_ModelName;
}
set
{
m_ModelName = value;
}
}
public string i_LicenseNumber
{
get
{
return m_LicenseNumber;
}
set
{
m_LicenseNumber = value;
}
}
}
}
public abstract class Engine
{
private float m_Current;
private float m_Max;
private float m_PercentageOfEnergyLeft;
public Engine(float i_Current, float i_Max)
{
m_Current = i_Current;
m_Max = i_Max;
m_PercentageOfEnergyLeft = 0;
}
public float i_Current
{
get
{
return m_Current;
}
set
{
m_Current = value;
}
}
public float i_Max
{
get
{
return m_Max;
}
set
{
m_Max = value;
}
}
public float i_PercentageOfEnergyLeft
{
get
{
return m_PercentageOfEnergyLeft;
}
set
{
m_PercentageOfEnergyLeft = value;
}
}
}
}
public class WorkedOnFuel : Engine
{
public enum eFuelType
{
Soler,
Octan95,
Octan96,
Octan98
}
private float m_CurrentFuelAmount;
private float m_MaxFuelAmount;
private eFuelType m_FuelType;
public WorkedOnFuel(eFuelType i_Fueltype, float i_CurrentFuelAmount, float i_MaxFuelAmount) : base(i_CurrentFuelAmount,i_MaxFuelAmount)
{
m_FuelType = i_Fueltype;
m_CurrentFuelAmount = i_CurrentFuelAmount;
m_MaxFuelAmount = i_MaxFuelAmount;
}
public eFuelType i_Fueltype
{
get
{
return m_FuelType;
}
set
{
m_FuelType = value;
}
}
public float i_CurrentFuelAmount
{
get
{
return m_CurrentFuelAmount;
}
set
{
m_CurrentFuelAmount = value ;
}
}
public float i_MaxFuelAmount
{
get
{
return m_MaxFuelAmount;
}
set
{
m_MaxFuelAmount = value;
}
}
public virtual void AddEnergyToEngine(eFuelType i_Type, float i_FuelAmountForAdd)
{
if (i_Type == i_Fueltype && i_CurrentFuelAmount + i_FuelAmountForAdd <= i_MaxFuelAmount)
{
i_CurrentFuelAmount += i_FuelAmountForAdd;
i_PercentageOfEnergyLeft = i_CurrentFuelAmount / i_MaxFuelAmount;
}
}
}
}
public class WorkedOnElectricity : Engine
{
private float m_BatteryTime;
private float m_MaxBatteryTime;
public WorkedOnElectricity(float i_BatteryTime, float i_MaxBatteryTime): base(i_BatteryTime,i_MaxBatteryTime)
{
m_BatteryTime = i_BatteryTime;
m_MaxBatteryTime = i_MaxBatteryTime;
}
public float i_BatteryTime
{
get
{
return m_BatteryTime;
}
set
{
m_BatteryTime = value;
}
}
public float i_MaxBatteryTime
{
get
{
return m_MaxBatteryTime;
}
set
{
m_MaxBatteryTime = value;
}
}
public virtual void AddEnergyToEngine(float i_HoursToAddTobattery)
{
if ((m_BatteryTime + i_HoursToAddTobattery) <= m_MaxBatteryTime)
{
i_MaxBatteryTime += i_HoursToAddTobattery;
i_PercentageOfEnergyLeft = i_BatteryTime / i_MaxBatteryTime;
}
}
}
}
the result that i need is that when ill do in main program Vehicle v = new FuelCar(...) v.i_Engine.---- ill get the methods of electricity/fuel by the car type of engine.(which was built in the constructor.
the fuel car class:
public class FuelCar : Car
{
private float m_CurrentFuelAmountInCar;
public FuelCar(string i_ModelName, string i_LicenseNumber, int i_NumberOfDoors, eColor i_ColorType, float i_CurrentPressureInWheel,
float i_CurrentFuelAmountInCar): base(i_ModelName, i_LicenseNumber,i_NumberOfDoors,i_ColorType,i_CurrentPressureInWheel)
{
i_Engine = new WorkedOnFuel(WorkedOnFuel.eFuelType.Octan98, 0, 45);
i_Engine.i_Current = i_CurrentFuelAmountInCar; // עידכון כמות הדלק
i_Engine.i_PercentageOfEnergyLeft = i_CurrentFuelAmountInCar / i_Engine.i_Max; // חישוב אחוז שנשאר במנוע
}
public float i_CurrentFuelAmountInCar
{
get
{
return m_CurrentFuelAmountInCar;
}
set
{
m_CurrentFuelAmountInCar = value;
}
}
}
}
thanks a lot for the help and sorry for my english and the specify question! ben.
Upvotes: 1
Views: 147
Reputation: 761
I believe that what you're asking for is a "downcast". C# has statements that handle this operation elegantly in my opinion. The "as" operator can be used to determine the type of an object pretty readily. In addition, there is a method called IsInstanceOfType on the Type class.
Documentation for the "as" operator: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/as
Documentation for the "IsInstanceOfType" method: https://msdn.microsoft.com/en-us/library/system.type.isinstanceoftype%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
Using the "as" operator to determine a type of derived class and thus give you the ability to call the derived class's methods looks like this:
Vehicle vehicle1 = new FuelCar(...);
Vehicle vehicle2 = new ElectricCar(...);
.
.
.
FuelCar fuelCar = vehicle1 as FuelCar;
if (fuelCar != null)
{
fuelCar.CallAFuelCarMethod();
}
ElectricCar electricCar = vehicle2 as ElectricCar;
if (electricCar != null)
{
electricCar.CallAnElectricCarMethod();
}
.
.
.
Using the IsInstanceOfType method is similar:
if (vehicle.GetType().IsInstanceOfType(typeof(FuelCar))
{
.
.
.
}
There are likely other methods; however, these two are simple solutions.
Upvotes: 1