C# ООП basics - Помощ със задача Vehicles от Polymorphism
Здравейте,
Това е моят код на решението, като изпитвам проблем с намирането на начин как да намалявам количествтото гориво след всеки Drive
using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Globalization;
namespace _06PolymorphismProblem01
{
class Vehicle
{
private string name;
private double fuelQuantity;
private double fuelConsumption;
public Vehicle(string name, double fuelQuantity, double fuelConsumption)
{
this.name = name;
this.fuelQuantity = fuelQuantity;
this.fuelConsumption = fuelConsumption;
}
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public double FuelQuantity
{
get
{
return fuelQuantity;
}
set
{
fuelConsumption = value;
}
}
public double FuelConsumption
{
get
{
return fuelConsumption;
}
set
{
fuelConsumption = value;
}
}
public virtual string Drive(double distanceToDrive)
{
if (distanceToDrive * this.fuelConsumption <= this.FuelQuantity)
{
return String.Format("{0} travelled {1} km", this.name, distanceToDrive);
}
else
{
return String.Format("{0} needs refueling", this.name);
}
}
public virtual void Refuel(double quantityToRefuel)
{
this.fuelQuantity += quantityToRefuel;
}
public virtual string GetInfo()
{
return String.Format("{0}: {1}", this.name, this.fuelQuantity);
}
}
class Car : Vehicle
{
private double additionalConsumption;
public Car(string name, double fuelQuantity, double fuelConsumption) : base(name, fuelQuantity, fuelConsumption)
{
this.additionalConsumption = 0.9;
}
public override string Drive(double distanceToDrive)
{
if (distanceToDrive * (this.FuelConsumption + additionalConsumption) <= this.FuelQuantity)
{
return String.Format("{0} travelled {1} km", this.Name, distanceToDrive);
}
else
{
return String.Format("{0} needs refueling", this.Name, distanceToDrive);
}
}
}
class Truck : Car
{
private double additionalConsumption;
private double fuelLossIndex;
public Truck(string name, double fuelQuantity, double fuelConsumption) : base(name, fuelQuantity, fuelConsumption)
{
this.additionalConsumption = 1.6;
this.fuelLossIndex = 0.95;
}
public override void Refuel(double quantityToRefuel)
{
this.FuelQuantity += quantityToRefuel * fuelLossIndex;
}
}
class Vehicles
{
static void Main(string[] args)
{
string[] input;
input = Regex.Split(Console.ReadLine(), @"\s+");
Car car = new Car(input[0], double.Parse(input[1], CultureInfo.InvariantCulture), double.Parse(input[2], CultureInfo.InvariantCulture));
input = Regex.Split(Console.ReadLine(), @"\s+");
Truck truck = new Truck(input[0], double.Parse(input[1], CultureInfo.InvariantCulture), double.Parse(input[2], CultureInfo.InvariantCulture));
int n = int.Parse(Console.ReadLine());
string[] command;
for (int i = 0; i < n; i++)
{
command = Regex.Split(Console.ReadLine(), @"\s+");
if (command[0] == "Drive")
{
if (command[1] == "Car")
{
Console.WriteLine(car.Drive(double.Parse(command[2], CultureInfo.InvariantCulture)));
}
else if (command[1] == "Truck")
{
Console.WriteLine(truck.Drive(double.Parse(command[2], CultureInfo.InvariantCulture)));
}
else
{
continue;
}
}
else if (command[0] == "Refuel")
{
if (command[1] == "Car")
{
car.Refuel(double.Parse(command[2], CultureInfo.InvariantCulture));
}
else if (command[1] == "Truck")
{
truck.Refuel(double.Parse(command[2], CultureInfo.InvariantCulture));
}
else
{
continue;
}
}
else
{
continue;
}
}
Console.WriteLine("{0}", car.GetInfo());
Console.WriteLine("{0}", truck.GetInfo());
}
}
}
Благодаря предварително за коментарите
Но не хвърляй грешки, когато съобщенията не са грешки :)
А какво правим когато съобщенията не са грешки?
Премисляме дали съобщението наистина се emit-ва от този, който върши работата. Drive() методът в случая, не трябва да emit-ва съобщение, а по-скоро трябва да движи превозното средство. Този, който обаче извиква Drive() метода е по-комплексен метод, който евентуално събира двете неща - кара превозното средство да се движи и принтира съобщение.
В общия случай на приложенията има един event loop/message loop, който държи приложението alive, докато някой не го затвори. Dispatcher-а в този loop се грижи за това да обработва потребителските действия и на база на приложния изход да уведомява потребителя какво се е случило.
Най-просто обяснено, имаме метод, който слуша за потребителски вход от типа на "Drive something", извиква Drive() и принтира на конзолата. Това е слоят най-близко до потребителя.
В по-абстрактния случай, този процесор на съобщения и събития работи с някакъв клас/интерфейс, който има възможност да уведомява потребителя със съобщения. Този клас можем за кратко да го наричаме Writer. Ако бъде подаден ConsoleWriter, неговият метод Write() ще пише на конзолата, докато е WindowsWriter евентуално ще отпечатва на Message Box и т.н.
Иначе казано най-простият вариант в случая (псевдокод) е
case "Drive something":
DispatchDriveCommand(vehicles[vehicleType]);
...
static void DispatchDriveCommand (Vehicle vehicle) {
vehicle.Drive();
WriteLine("The {0} drove {1} km", vehicle.Type, vehicle.Kilometers);
}