— Привіт, Аміго! Зараз буде одна тема, якою, я думаю, ти частенько користуватимешся. Це – успадкування.
Програмування, для необізнаних, не відрізняється від магії. Тому почну з цікавої аналогії…
Припустимо, що ти чарівник і хочеш створити літаючого коня. З одного боку, ти міг би спробувати начарувати пегаса. Але оскільки пегасів у природі немає, це буде дуже непросто. Доведеться багато робити самому. Значно простіше взяти коня і начарувати йому крила.

У програмуванні такий процес називається «успадкування». Припустимо, тобі треба написати дуже складний клас. Писати з нуля довго, потім ще довго все тестувати та шукати помилки. Навіщо йти найскладнішим шляхом? Краще пошукати – а чи немає такого класу?
Припустимо, ти знайшов клас, який своїми методами реалізує 80% потрібної функціональності. Ти можеш просто скопіювати код у свій клас. Але таке рішення має кілька мінусів:
1) Знайдений клас вже може бути скомпільований у байт-код, а доступу до його вихідного коду в тебе немає.
2) Вихідний код класу є, але ти працюєш у компанії, яку можуть засудити на пару мільярдів за використання навіть шести рядків чужого коду. А потім вона засудить тебе.
3) Непотрібне дублювання великого обсягу коду. Крім того, якщо автор чужого класу знайде у ньому помилку та виправить її, у тебе ця помилка залишиться.
Є рішення більш вишукане, і без необхідності отримувати легальний доступ до коду оригінального класу. У Java ти можеш просто оголосити той клас батьком твого класу. Це буде еквівалентно тому, що ти додав код того класу до свого коду. У твоєму класі з'являться всі дані та всі методи батьківського класу. Наприклад, можна робити так: успадковуємося від «коня», додаємо «крила» — отримуємо «пегаса»

— Дуже цікаво, продовжуй.
— Успадкування можна використовувати і для інших цілей. Наприклад, у тебе є десять класів, які дуже схожі, мають дані та методи, що збігаються. Ти можеш створити спеціальний базовий клас, винести ці дані (і методи, що з ними працюють) у цей базовий клас і оголосити ті десять класів його нащадками. Тобто вказати у кожному класі, що у нього є батьківський клас – даний базовий клас.
Так само як переваги абстракції розкриваються лише поряд з інкапсуляцією, так і переваги успадкування значно сильніші, якщо використовується поліморфізм. Але про нього я розповім потім. Зараз ми розглянемо кілька прикладів використання успадкування.
Припустимо, ми пишемо програму, яка грає у шахи з користувачем, тоді нам знадобляться класи для фігур. Які б ти запропонував класи, Аміго?
— Король, Ферзь, Слон, Кінь, Тура і Пішак.
— Чудово. Нічого не прогавив.
— А які б дані ти запропонував зберігати у цих класах?
— Координати x та y, а також її цінність (worth). Адже деякі фігури цінніші за інші.
— А у чому відмінності цих класів?
— Відмінності у тому, як вони ходять, фігури. У поведінці.
— Так. Ось як можна було б описати їх у вигляді класів
|
|
|
|
|
|
— Так, саме так я б і написав.
— А ось як можна було б скоротити код за допомогою успадкування. Ми могли б винести однакові методи та дані до загального класу. Назвемо його ChessItem. Об'єкти класу ChessItem немає сенсу створювати, оскільки йому не відповідає жодна шахова фігура,проте від нього було би багато користі:
|
|
|
|
||
|
|
|
— Як цікаво.
— Саме так! Особливо багато переваг ми отримуємо, коли у проєкті тисячі різних об'єктів та сотні класів. Тоді правильно підібраними класами можна не лише суттєво спростити логіку, а й скоротити код у десятки разів.
— А що потрібно, щоб успадкувати якийсь клас?
— Для цього після оголошення нашого класу потрібно вказати ключове слово extends та написати ім'я батьківського класу. Успадкуватися можна лише від одного класу.

На картинці ми бачимо «корову», успадковану від «свині». «Свиня» успадкована від «курки», «курка» від «яйця». Лише один батько! Таке успадкування не завжди є логічним. Але якщо є тільки свиня, а дуже потрібна корова, програміст часто не може встояти перед бажанням зробити «корову» зі «свині».
— А якщо мені хочеться успадкуватись від двох класів. Можна ж щось зробити?
— Майже нічого. Множинного успадкування класів у Java немає: клас може мати лише один батьківський клас. Але є множинне наслідування інтерфейсів. Це трохи знижує гостроту проблеми.
— Ясно. А що таке інтерфейс?
— Про інтерфейси я розповім тобі наступного разу, а поки що давай продовжимо розбиратися з успадкуванням.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ