Pull to refresh

Наследование 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();
            }


        }

    }
}
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.