Лекція 15: Успадкування (Inheritance)
1. Що таке Успадкування?
Уявіть, що ви створюєте гру. У ній є вороги: "Enemy", "Orc", "Zombie". У всіх є здоров'я (hp), швидкість (speed) і метод attack(). Замість того, щоб писати цей код тричі (для кожного монстра), ми створюємо Базовий клас (Батьківський), який містить спільні характеристики. Інші класи стають Нащадками (Похідними) цього базового класу.
- Базовий клас (Parent/Base): Містить спільні характеристики.
- Похідний клас (Child/Derived): Отримує все від батька + додає свої унікальні риси.
2. Синтаксис
Щоб зробити один клас спадкоємцем іншого, використовується двокрапка : після назви класу.
#include <iostream>
using namespace std;
class Animal { // Базовий клас (Base Class)
public:
void eat() {
cout << "Я їм..." << endl;
}
};
// Клас Dog успадковує Animal
class Dog : public Animal {
public:
void bark() {
cout << "Гав-гав!" << endl;
}
};
int main() {
Dog myDog;
myDog.eat(); // Цей метод прийшов від Animal!
myDog.bark(); // А цей метод свій власний.
return 0;
}
3. Модифікатор доступу protected
Ми знаємо: public — доступно всім, private — тільки самому класу. Успадкування додає третій варіант: protected.
private: Навіть діти (похідні класи) НЕ бачатьprivateзмінні батька.protected: "Сімейні секрети". Змінні недоступні ззовні (якprivate), але діти мають до них доступ.
#include <iostream>
using namespace std;
class Device {
protected: // <--- УВАГА
int batteryLevel; // Доступно для Device і для Phone
public:
void charge() { batteryLevel = 100; }
};
class Phone : public Device {
public:
void call() {
// Ми бачимо batteryLevel, бо він protected
if (batteryLevel > 0) {
cout << "Дзвонимо..." << endl;
batteryLevel--;
}
}
};
int main() {
Phone p;
p.charge();
p.call();
return 0;
}
Якби batteryLevel був private, клас Phone видав би помилку при спробі його змінити.
4. Порядок виклику конструкторів
Це важливе питання на співбесіді! При створенні об'єкта Похідного класу C++ спочатку "будує фундамент".
- Спочатку викликається конструктор Базового класу (Батька).
- Потім викликається конструктор Похідного класу (Дитини).
При знищенні об'єкта деструктори спрацьовують у зворотному порядку.
Як передати параметри батькові?
Якщо у Батька є конструктор з параметрами, Дитина зобов'язана його викликати через список ініціалізації.
#include <iostream>
#include <string>
using namespace std;
class Person {
public:
string name;
Person(string n) { // Конструктор батька вимагає ім'я
name = n;
}
};
class Student : public Person {
public:
int course;
// Ми передаємо 'n' далі нагору, в конструктор Person
Student(string n, int c) : Person(n) {
course = c;
}
};
int main() {
Student s("Ivan", 2);
cout << s.name << " на " << s.course << " курсі" << endl;
return 0;
}
5. Перевизначення методів (Overriding)
Нащадок може змінити поведінку методу, який отримав від батька. Для цього треба просто оголосити метод з такою самою назвою.
#include <iostream>
using namespace std;
class Animal {
public:
void speak() {
cout << "Якась тварина видає звук" << endl;
}
};
class Cat : public Animal {
public:
// Перевизначаємо (замінюємо) батьківський метод
void speak() {
cout << "Мяу!" << endl;
}
};
int main() {
Cat myCat;
myCat.speak(); // Виведе "Мяу!" (не "Якась тварина видає звук")
return 0;
}
Практичні завдання до Лекції 15
Виконайте ці завдання в своєму середовищі розробки.
Завдання 1: Транспорт
- Створіть базовий клас
Vehicleз полемspeed(protected) та методомdrive()(виводить "Ідемо зі швидкістю..."). - Створіть клас
Car, який успадковуєVehicle.- Додайте унікальне поле
wheels(кількість коліс). - Додайте метод
honk()(виводить "Біп-біп!").
- Додайте унікальне поле
- У
mainстворітьCar, задайте швидкість (через метод або конструктор) і викличте методиdrive()таhonk().
Завдання 2: Студент та Викладач (Спільне минуле)
- Створіть базовий клас
Humanз полямиnameтаage. Зробіть конструктор, який їх заповнює. - Створіть клас
Student, який успадковуєHumanі додає полеaverageScore(середній бал). - Створіть клас
Teacher, який успадковуєHumanі додає полеsalary(зарплата). - Напишіть конструктори для
StudentіTeacher, які передають ім'я та вік у батьківський конструкторHuman. - Створіть по одному об'єкту кожного класу і виведіть всю інформацію про них.
Завдання 3: Банківська таємниця (Protected)
- Створіть клас
Accountіз полемbalance(protected). - Додайте метод
deposit(amount)у класAccountдля поповнення. - Створіть клас
PremiumAccount, який успадковуєAccount. - У
PremiumAccountдодайте методaddBonus(). Логіка: якщо на балансі більше 1000 грн, додати ще 50 грн бонусу (змінитиbalanceнапряму). - Мета: Переконатися, що клас-нащадок має доступ до
protectedполяbalance, і що цей код працює.