Как стать автором
Обновить

Наследование C#

Простота — залог надежности. Edsger W. Dijkstra

Здравствуйте! Сегодня я бы хотел рассказать о наследовании. Многие новички когда начинают изучать какой-либо язык программирования сталкиваются с проблемами на своем пути. Не компилируется программа, вылетает, скобочки не хватает - это то, чего не избежать. С личного опыта хочу сказать, что мне действительно нахватало наставника, своего рода учителя как в Звездных Войнах. Что бы взял за руку, повел в правильном направлении и указал на ошибки.

Мне бы хотелось помочь ребятам подробнее разобраться и улучшить свои знания в области программирования, а именно в теме наследование в C#.

Задача: Создать базовый класс “Транспорт”. От него наследовать “Авто”, “Самолет”, “Поезд”. От класса “Авто” наследовать классы “Легковое авто”, “Грузовое авто”. От класса “Самолет” наследовать классы “Грузовой самолет” и “Пассажирский самолет”. Придумать поля для базового класса, а также добавить поля в дочерние классы, которые будут конкретно характеризовать объекты дочерних классов. Определить конструкторы, методы для заполнения полей классов (или использовать свойства). Написать метод, который выводит информацию о данном виде транспорта и его характеристиках. Использовать виртуальные методы.

И так, вы прочитали задачу. Первое, что я рекомендую сделать, это нарисовать, где вам удобно, схему проекта. Классы, поля, методы, возможно интерфейсы и т.д. В общем говоря составьте UML таблицу. Поздравляю, вы уже готовы создавать.

1) Создадим класс “Транспорт”. Должно получится следующее:

namespace ConsoleApp1
{
    public abstract class Transport
        {
        }
}

Если вы пишете код в VS у вас будут подключены библиотеки:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

Теперь давайте создадим поля, методы, конструктор по умолчанию и с параметрами.

namespace ConsoleApplication1
{
    public abstract class Transport
        {
            public int Year { get; set; }
            public int Weight { get; set; }
            public string Color { get; set; }

            protected Transport() { }

            protected Transport(int year, int weight, string color)
            {
                Year = year;
                Weight = weight;
                Color = color;
            }

            public abstract void Info();
        }
}

Ура! Мы написали базовый класс от которого будем наследовать дочерние классы. Условно строить машину, класс Transport это указания для ВСЕГО транспорта какой год выпуска (поле Year), вес (поле Weight), цвет (поле Color). И абстрактный метод Info, который будет выводить информацию например так: Машина -Ford Explorer. Вес - 1670 кг. Год - 2019. Цвет - черный и т.д. Еще мы описали 2 типа конструктора:

protected Transport() { }
protected Transport(int year, int weight, string color)
{
  Year = year;
  Weight = weight;
  Color = color;
}

Конструктор это специальный блок инструкций, вызываемый при создании объекта. То есть, первый инструктор когда мы например создаем объект класса:

Transport transport = new Transport();

В таком случае мы создадим объект transport класса Transport. С параметрами по умолчанию. Что это означает? Это означает что поля Year, Weight, Color получат значения (Year = null, Weight = null, Color = null). Это сделано для того, что бы при выделении памяти в них не было мусора. Также мы можем сделать следующее:

protected Transport() 
{ 
	Year = 0;
  Weight = 0;
  Color = "Unknown";
}
protected Transport(int year, int weight, string color)
{
  Year = year;
  Weight = weight;
  Color = color;
}

Тут мы явно присвоили полям какие-то свои значения.

Второй конструктор это то же самое присвоение значений, но только когда мы передаем в конструктор int year, int weight, string color:

Transport transport = new Transport(2019, 1634, "Black");

Что такое protected и public? Public — доступ открыт всем другим классам, кто видит определение данного класса. Protected — доступ открыт классам, производным от данного. То есть, производные классы получают свободный доступ к таким свойствам или метода. Все другие классы такого доступа не имеют.

Но, так как мы создали не просто класс, а абстрактный класс, нам не удастся создать его объект. Так как объект абстрактного класса создать нельзя.

2) Давайте создадим классы “Авто”, “Самолет”, “Поезд”:

using System;
namespace ConsoleApp1
{
    class Train : Transport
    {
        public int Сarriages { get; set; }
        public Train(int year, int weight, string color, int carriages) : base(year, weight, color)
        {
            Сarriages = carriages;
        }

        public override void Info()
        {
            Console.WriteLine("Train");
            Console.WriteLine($"Year: {Year}\n" +
                              $"Weight: {Weight}\n" +
                              $"Color: {Color}");
            Console.WriteLine($"Сarriages: {Сarriages}\n");
        }
    }
}
using System;
namespace ConsoleApp1
{
    public class Airplane : Transport
    {
        public double WingLength { get; set; }
        public Airplane(int year, int weight, string color, double wingLength) : base(year, weight, color)
        {
            WingLength = wingLength;
        }

        public override void Info()
        {
            Console.WriteLine("Airplane");
            Console.WriteLine($"Year: {Year}\n" +
                              $"Weight: {Weight}\n" +
                              $"Color: {Color}");
            Console.WriteLine($"WingLength: {WingLength:0.00}\n");
        }
    }
}
using System;
namespace ConsoleApp1
{
    public class Car : Transport
    {
        public double Speed { get; set; }
        public Car(int year, int weight, string color, double speed) : base(year, weight, color)
        {
            Speed = speed;
        }

        public override void Info()
        {
            Console.WriteLine("Car");
            Console.WriteLine($"Year: {Year}\n" +
                              $"Weight: {Weight}\n" +
                              $"Color: {Color}");
            Console.WriteLine($"Speed: {Speed:0.00}\n");
        }
    }
}

Мы успешно создали 3 класса. Добавили поле Speed для Car, WingLength для Airplane, Сarriages для Train, реализовали абстрактный метод класса Transport.

Так как классы очень походи давайте разберем только один, например Car.

public class Car : Transport

Этот синтаксис означает что мы публично унаследовали класс родителя Transport. Также унаследовали поля родителя:

 public Car(int year, int weight, string color, double speed) 
   : base(year, weight, color)

Далее переопределили метод Info() также родителя. Ключевое слово override означает что мы как раз это и сделали.

public override void Info()

3) Теперь давайте создадим классы и унаследуем их от родителя Auto “Легковое авто”, “Грузовое авто”:

using System;

namespace ConsoleApp1
{
    public class Truck : Car
    {
        public double BodyLength { get; set; }
        public Truck(int year, int weight, string color, double speed, double bodyLength) : base(year, weight, color, speed)
        {
            BodyLength = bodyLength;
        }

        public override void Info()
        {
            Console.WriteLine("Truck");
            Console.WriteLine($"Year: {Year}\n" +
                              $"Weight: {Weight}\n" +
                              $"Color: {Color}\n" +
                              $"Speed: {Speed:0.00}");
            Console.WriteLine($"BodyLength: {BodyLength:0.00}\n");
        }
    }
}
using System;

namespace ConsoleApp1
{
    public class Passenger : Car
    {
        public string PassengerType { get; set; }
        public Passenger(int year, int weight, string color, double speed, string passengerType) : base(year, weight, color, speed)
        {
            PassengerType = passengerType;
        }

        public override void Info()
        {
            Console.WriteLine("Truck");
            Console.WriteLine($"Year: {Year}\n" +
                              $"Weight: {Weight}\n" +
                              $"Color: {Color}\n" +
                              $"Speed: {Speed:0.00}");
            Console.WriteLine($"PassengerType: {PassengerType}\n");
        }
    }
}

Тут ничего сложного, все по аналогии. Теперь нужно создать последние классы: “Грузовой самолет” и “Пассажирский самолет”:

using System;

namespace ConsoleApp1
{
    public class PassengerPlane : Airplane
    {
        public int Seats { get; set; }
        public PassengerPlane(int year, int weight, string color, double wingLength, int seats) : base(year, weight, color, wingLength)
        {
            Seats = seats;
        }

        public override void Info()
        {
            Console.WriteLine("Airplane");
            Console.WriteLine($"Year: {Year}\n" +
                              $"Weight: {Weight}\n" +
                              $"Color: {Color}\n" +
                              $"WingLength: {WingLength:0.00}");
            Console.WriteLine($"Seats: {Seats}\n");
        }
    }
}
using System;

namespace ConsoleApp1
{
    public class CargoPlane : Airplane
    {
        public double Capacity { get; set; }
        public CargoPlane(int year, int weight, string color, double wingLength, double capacity) : base(year, weight, color, wingLength)
        {
            Capacity = capacity;
        }

        public override void Info()
        {
            Console.WriteLine("Airplane");
            Console.WriteLine($"Year: {Year}\n" +
                              $"Weight: {Weight}\n" +
                              $"Color: {Color}\n" +
                              $"WingLength: {WingLength:0.00}");
            Console.WriteLine($"Capacity: {Capacity:0.00}\n");
        }
    }
}

Тут также все по антологии.

Вот и все что нужно было сделать. Теперь давайте проверим все ли работает. Создадим объекты классов:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{

    class Program
    {
        

        static void Main(string[] args)
        {
            Random rand = new Random();
            string[] colors = new string[] { "Blue", "Black", "Red", "Green", "Yellow" };
            string[] passengerType = new string[] { "WithBody", "WithoutBody" };
            

            Transport[] arr = new Transport[10];
            
            for (int i = 0; i < arr.Length; i++)
            {
                switch (rand.Next(5))
                {
                   
                    case 0:
                        string colorPassanger = colors[rand.Next(0, colors.Length)];
                        string type = passengerType[rand.Next(0, passengerType.Length)];
                        arr[i] = new Passenger(rand.Next(18, 45), rand.Next(500), colorPassanger, rand.NextDouble() * 30 + 210, type);
                        break;
                    case 1:
                        string colorTruck= colors[rand.Next(0, colors.Length)];
                        arr[i] = new Truck(rand.Next(20, 50), rand.Next(5000), colorTruck, rand.NextDouble() * 10 + 120, rand.NextDouble() * 2 + 3);
                        break;
                    case 2:
                        string colorCargoPlane = colors[rand.Next(0, colors.Length)];
                        arr[i] = new CargoPlane(rand.Next(60, 150), rand.Next(50000), colorCargoPlane, rand.NextDouble() * 5 + 10, rand.NextDouble() * 5000 + 7000);
                        break;
                    case 3:
                        string colorPassengerPlane = colors[rand.Next(0, colors.Length)];
                        arr[i] = new PassengerPlane(rand.Next(60, 150), rand.Next(50000), colorPassengerPlane, rand.NextDouble() * 5 + 10, rand.Next(120));
                        break;
                    case 4:
                        string colorTrain = colors[rand.Next(0, colors.Length)];
                        arr[i] = new Train(rand.Next(150, 250), rand.Next(100000), colorTrain, rand.Next(10));
                        break;
                   
                }
            }
            foreach (var transport in arr)
            {
                transport.Info();
            }


        }

    }
}
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.