Урок №167. Перевизначення методів батьківського класу

  Юрій  | 

  Оновл. 27 Вер 2021  | 

 151

Дочірні класи за замовчуванням наслідують всі методи батьківського класу. На цьому уроці ми розглянемо, як це відбувається, а також те, як можна змінити методи батьківських класів в дочірніх класах.

Виклик методів батьківського класу

При виклику методу через об’єкт дочірнього класу, компілятор спочатку дивиться, чи існує цей метод в дочірньому класі. Якщо ні, то він починає просуватися по “ланцюжку” спадкування вгору і перевіряє, чи був цей метод визначений в будь-якому з батьківських класів. Компілятор використовуватиме перше знайдене визначення. Наприклад:

Результат виконання програми:

I am a Parent!
I am a Parent!

При виклику child.identify(), компілятор дивиться, чи визначений метод identify() в класі Child. Ні, тому компілятор переходить до класу Parent. У класі Parent є визначення методу identify(), тому компілятор використовує саме це визначення.

Перевизначення методів батьківського класу

Однак, якби ми визначили метод identify() в класі Child, то використовувалося б саме це визначення. Це означає, що ми можемо змусити батьківські методи працювати по-іншому з нашими дочірніми класами, просто перевизначаючи їх в дочірніх класах!

Вищенаведений приклад стане кращим, якщо child.identify() виводитиме I am a Child!. Давайте змінимо метод identify() в класі Child так, щоб він повертав правильну відповідь.

Перевизначення батьківського методу в дочірньому класі відбувається, як звичайне визначення методу:

Ось той же код функції main(), що і у вищенаведеному прикладі, але вже з внесеними змінами в клас Child:

Результат:

I am a Parent!
I am a Child!

Зверніть увагу, коли ми перевизначаємо батьківський метод в дочірньому класі, то дочірній метод не наслідує специфікатор доступу батьківського методу з тим же ім’ям. Використовується той специфікатор доступу, який вказаний в дочірньому класі. Таким чином, метод, визначений як private в батьківському класі, може бути перевизначений як public в дочірньому класі, або навпаки!

Розширення функціоналу батьківських методів

Можуть бути випадки, коли нам не потрібно повністю замінювати метод батьківського класу, але потрібно просто розширити його функціонал. Зверніть увагу, у вищенаведеному прикладі метод Child::identify() повністю перекриває Parent::identify()! Можливо, це не те, що нам потрібно. Ми можемо викликати метод батьківського класу з тим же ім’ям в методі дочірнього класу (для повторного використання коду), а потім додати свій код.

Щоб метод дочірнього класу викликав метод батьківського класу з тим же ім’ям, потрібно просто виконати звичайний виклик функції, але з доданням імені батьківського класу і оператора дозволу області видимості. У наступному прикладі ми виконаємо перевизначення identify() в класі Child, викликаючи спочатку Parent::identify(), а потім додаючи вже свій код:

Разом з:

Дає результат:

I am a Parent!
I am a Parent!
I am a Child!

При виконанні child.identify() виконується виклик Child::identify(). У Child::identify() ми спочатку викликаємо Parent::identify(), який виводить I am a Parent!. Коли Parent::identify() завершує своє виконання, Child::identify() продовжує своє виконання і виводить I am a Child!.

Все просто. Навіщо тоді потрібно використовувати оператор дозволу області видимості (::)? А потім, що, якби ми визначили Child::identify() наступним чином:

То виклик методу identify() без вказування оператора дозволу області видимості призвів би до виклику identify() в поточному класі, тобто Child::identify(). Потім знову виклик Child::identify(), і ура — у нас вийшов нескінченний цикл. Тому використання оператора дозволу області видимості є обов’язковою умовою при зміні методів батьківського класу.

Оцінити статтю:

1 Зірка2 Зірки3 Зірки4 Зірки5 Зірок (4 оцінок, середня: 5,00 з 5)
Loading...

Залишити відповідь

Ваш E-mail не буде опублікований. Обов'язкові поля відмічені *