Идея полиморфизма заключается в подмене реализация одного и того же метода. Типичной фразой полиморфизм можно объяснить фразой "Один интерфейс, множество реализаций". В C# полиморфизм достигается за счет использования абстрактных и виртуальных методов. В теории все это дело понятно. Но как и главное когда использовать полиморфизм для новчиков становится серьезной проблемой. Данный пример призван улучшить понимание принципов полиморфизма и построения гибких программных конструкций.
Идея пример заключается в том, что у нас есть машины различных типов (Motobike, PassengerCar, Van, Minivan), каждая из которых может быть обсужена на заправке (GasStation) и при этом имеет различную вместительность топливного бака (полиморфизм). Все автомобили наследованы от базового класса Car, который в свою очередь реализует интерфейс ICar. Зависимости всех классов нашей системы показаны на диаграмме выше. Так-как вместительность бака (FuelLimit) помечена ключевым словом virtual, то любой класс наследник может переопределить его поведение. Это и происходит в классах наследниках (Motobike, Van). На вход заправки (GasStation) приходит параметр типа ICar, который может принимать различную форму (быть классами Motobike, Van), вот здесь и кроется полиморфизм.
Пример ICar и Car
/// <summary> /// Define the general information about car /// </summary> interface ICar { /// <summary> /// Max level of fuel in the tank /// </summary> int FuelLimit { get; } /// <summary> /// Current level of fuel in the tank /// </summary> int Fuel { get; set; } /// <summary> /// Name of the car /// </summary> string Name { get; } }
abstract class Car : ICar { public int Fuel { get; set; } public Car() { // all cars start with 20 units of fuel Fuel = 20; } /// <summary> /// Virtual, because we have default limit for any derived car. Derived car can ovveride or not this property /// </summary> public virtual int FuelLimit { get { return 50; } } /// <summary> /// Abstract, because derived class must ovveride /// </summary> public abstract string Name { get; } }
Пример GasStation
class GasStation { public void FillFuel(ICar car, int fuel) { if (car == null) { Console.WriteLine("Car is broken"); return; } if (car.Fuel + fuel > car.FuelLimit) { Console.WriteLine($"Can't fill the {car.Name}, because limit {car.FuelLimit} achieved"); return; } car.Fuel += fuel; Console.WriteLine($"{car.Name} was filled, current fuel level is {car.Fuel}"); } }
Пример заправки различных автомобилей
// array of cars ICar[] cars = new ICar[] { new Motobike(), new PassengerCar(), new Van() }; // init gas station GasStation gasStation = new GasStation(); // fill all availabe cars foreach(ICar car in cars) { gasStation.FillFuel(car, 23); }
P.S. Очень важно, для запуска этого проекта вам потребуется Visual Studio 2015, так-как в проекте используются конструкции C# 6.0.
dmytro