У цьому уроці ми розглянемо з вами один з базових принципів об'єктно-орієнтованого програмування - успадкування.
Розпочнемо розгляд спадкування з життєвих ситуацій. Для прикладу, візьмемо такі поняття, як людина і студент. У кожної людини є ім'я, зріст, вага і інші загальні характеристики. Студент же є окремим випадком людини, у нього також є ім'я, зріст, вага, але крім цього, він вчиться в деякому ВУЗі, на певної спеціальності і має середній бал. З погляду успадкування, в цьому випадку, студент є спадкоємцем поняття людина. Ще один приклад можна навести з тваринами. Тварина - це загальне поняття. Тварин можна поділити на риб, птахів і ссавців. Кожен з цих груп тварин розрізняються деяким характеристиками, але у всіх них є спільні особливості тварин.
А тепер перейдемо до програмування
У програмуванні спадкування дозволяє створювати новий клас на базі іншого. Клас, на базі якого створюється новий клас, називається базовим, а базується новий клас - спадкоємцем або похідним класом. В клас-спадкоємець з базового класу переходять поля, властивості, методи і інші члени класу.
Оголошення нового класу, який буде наслідувати інший клас, виглядає так:
class [ім'я_класу]: [імя_базового_класса]
{
// Тіло класу
}
Наведу простий приклад використання успадкування. На основі базового класу Тварина створюються два класи Собака і Кішка, у ці два класи переходить властивість Ім'я тварини:
class Animal
{
public string Name {get; set; }
}
class Dog: Animal
{
public void Guard ()
{
// Собака охороняє
}
}
class Cat: Animal
{
public void CatchMouse ()
{
// Кішка ловить миша
}
}
class Program
{
static void Main (string [] args)
{
Dog dog1 = new Dog ();
dog1.Name = "Барбос"; // Називаємо пса
Cat cat1 = new Cat ();
cat1.Name = "Барсик"; // Називаємо кота
dog1.Guard (); // Відправляємо пса охороняти
cat1.CatchMouse (); // Відправляємо кота на полювання
}
}
Виклик конструктора базового класу в Сі-шарп
У базовому класі і класі-спадкоємця можуть бути оголошені конструктори, і тут виникає питання - який конструктор за що має відповідати, і як їх викликати. Логічно буде сказати те, що конструктор базового класу буде створювати ту частину об'єкта, яка належить базовому класу (адже з базового класу про спадкоємця нічого невідомо), а конструктор з спадкоємця буде створювати свою частину.
Коли конструктор визначений тільки в спадкоємця, то тут все просто - при створенні об'єкта спочатку викликається конструктор за замовчуванням базового класу, а потім конструктор спадкоємця.
Коли конструктори оголошені і в базовому класі, і в спадкоємця - нам необхідно викликати їх обидва. Для виклику конструктора базового класу використовується ключове слово base. Оголошення конструктора класу-спадкоємця з викликом базового конструктора має наступну структуру:
[імя_конструктора_класса-спадкоємця] ([аргументи]): base ([аргументи])
{
// Тіло конструктора
}
У базовий конструктор передаються всі необхідні аргументи для створення базової частини об'єкта.
Наведу приклад виклику базового конструктора. Є той же клас Тварина і клас Папуга. У класі Тварина є тільки властивість Ім'я, і конструктор, який дозволяє встановити це ім'я. У класі Папуга є властивість Довжина дзьоба і конструктор, в якому ми задаємо цю довжину. При створенні об'єкта Папуга ми вказуємо два аргументи - ім'я і дзьоб, і далі аргумент Ім'я передається в базовий конструктор, він викликається, і після його роботи виконання передається конструктору класу Папуга, де встановлюється довжина:
class Animal
{
public string Name {get; set; }
public Animal (string name)
{
Name = name;
}
}
class Parrot: Animal
{
public double BeakLength {get; set; } // Довжина дзьоба
public Parrot (string name, double beak): base (name)
{
BeakLength = beak;
}
}
class Dog: Animal
{
public Dog (string name): base (name)
{
// Тут може бути логіка створення об'єкта Собака
}
}
class Program
{
static void Main (string [] args)
{
Parrot parrot1 = new Parrot ("Кеша", 4.2);
Dog dog1 = new Dog ("Барбос");
}
}
Доступ до членів базового класу з класу-спадкоємця
Тут варто зазначити, що в класі-спадкоємця ми можемо отримати доступ до членів базового класу які оголошені як public, protected, internal і protected internal. Члени базового класу з модифікатором доступу private також переходять у клас-спадкоємець, але до них можуть мати доступ тільки члени базового класу. Наприклад, властивість, оголошене в базовому класі, яке управляє доступом до закритого полю, працюватиме коректно в класі-спадкоємця, але окремо отримати доступ до цього поля з класу-спадкоємця ми не зможемо.
Домашнє завдання
Створіть базовий клас Геометрична фігура, передбачте в ньому загальні поля / властивості, наприклад координати центру фігури, за допомогою конструктора повинна бути можливість задати центр. На базі цього класу створіть два нові - Трикутник і Окружність. У цих класах повинні бути свої особливі поля, наприклад радіус для кола. В обидва класу додайте метод Намалювати, в якому могла б бути специфічна логіка малювання фігури. Створіть об'єкти трикутник і коло.
PS. Не забуваємо підписуватися на оновлення по електронній пошті у формі нижче!