JavaRush /Java блог /Random UA /Кава-брейк #95. Як вирішити проблему множинного успадкува...

Кава-брейк #95. Як вирішити проблему множинного успадкування в Java

Стаття з групи Random UA
Джерело: FreeCodeCamp Java - одна з найпопулярніших об'єктно-орієнтованих мов програмування, що використовуються сьогодні. Оскільки він не залежить від платформи, ви можете знайти Java-програми на всіх типах пристроїв та в кожній операційній системі. А оскільки Java відносно легко вивчити, це одна з мов, яку освоює багато програмістів. Важлива особливість Java, з якою ви повинні бути знайомі, це спадкування класів. Спадкування дозволяє оптимізувати код, полегшуючи повторне використання класів. Коли ви можете повторно використовувати код, який вже був протестований та налагоджений, життєвий цикл розробки програмного забезпечення стає коротшим і менш витратним. Кава-брейк #95.  Як вирішити проблему множинного успадкування в Java - 1Хоча теоретично це проста концепція, кодування відносин успадкування потребує уваги деталей. Особливо щодо множинного успадкування, коли один дочірній клас успадковує властивості кількох батьківських класів. Java відкидає численні відносини успадкування, тому що вони створюють неоднозначність, але є кілька способів досягти багатьох з тих же ефектів, якщо ви знаєте, що робити. У цій статті ми розглянемо проблеми з множинним успадкуванням та обговоримо альтернативні варіанти кодування Java.

Термінологія наслідування

Іноді, щоб стати успішним програмістом, ви повинні навчитися вирішувати проблеми, щоб знайти обхідні шляхи для загальних помилок або проблем. Це необхідна частина безпечного та розумного кодування. Одна з таких проблем пов'язана з множинним успадкуванням (точніше, його відсутністю) Java. Кава-брейк #95.  Як вирішити проблему множинного успадкування в Java - 2Щоб повністю зрозуміти успадкування в Java, вам необхідно ознайомитись з базовою термінологією успадкування об'єктно-орієнтованого програмування (ООП).
  • Класи - це фундаментальна структура шаблону в об'єктно орієнтованих мовах програмування. Клас визначає загальні властивості групи об'єктів.
  • Батьківський клас : також відомий як базові класи чи суперкласи. Батьківський клас - це клас, що розширюється, який надає функції дочірньому класу. Він припускає можливість повторного використання. Визначення та функції батьківського класу повторно використовуються під час створення дочірніх класів.
  • Дочірній клас : більш узагальнено званий підклас, дочірній клас успадковує функції від іншого класу. Дочірні класи – це розширені чи похідні класи.
  • Спадкування : відносини між батьківським та дочірнім класами.

Типи успадкування ООП

Сьогодні використовується безліч популярних об'єктно-орієнтованих мов програмування, включаючи Java, C++, JavaScript, Python, PHP, Ruby та Perl. Хоча успадкування є загальною концепцією для цих мов ОВП, не всі типи успадкування існують у кожній з цих мов. Вкрай важливо знати загальні типи успадкування та обмеження на успадкування конкретною мовою, яку ви використовуєте. Чим більше ви знаєте про наслідування, тим ефективнішим розробником ви станете. Типи успадкування, підтримувані Java, включають:
  • Однорівневе наслідування : коли дочірній клас успадковує функції від єдиного батьківського класу.
  • Багаторівневе наслідування : це багаторівнева форма однорівневого наслідування. При багаторівневому наслідуванні дочірній клас також може бути батьківським класом для інших дочірніх класів. Відносини між кожним рівнем лінійні - ніякі гілки не виходять вище, ніж при множинному наслідуванні. І тут кінцевий дочірній клас має функції з усіх рівнів вище.
  • Ієрархічне успадкування : протилежність множинного успадкування. В ієрархічному наслідуванні єдиний батьківський клас має більше одного дочірнього класу. Таким чином, замість того, щоб мати гілки над ним, він розгалужується внизу.
  • Гібридне успадкування : як випливає з назви, гібридне успадкування є комбінацією інших типів успадкування.
На додаток до типів спадкування, вказаних вище, існують інші типи, які Java не підтримує.
  • Множинне успадкування : при множинному наслідуванні дочірній клас має більше одного батьківського класу. Хоча Java та JavaScript не підтримують множинне спадкування, такі мови ООП, як C++, підтримують.
  • Багатоколійне успадкування : гібрид множинного, багаторівневого та ієрархічного успадкування, при багатоколійному успадкування дочірній клас успадковує свої характеристики та функції від батьківського класу та кількох дочірніх класів батьківського класу. Оскільки багатоколійне успадкування ґрунтується на множинному успадкування, Java не підтримує його використання.

Чому Java не підтримує множинне спадкування

Основна проблема множинного успадкування у тому, що може створювати неоднозначності в дочірніх класах. В оглядовому технічному документі 1995 року провідний дизайнер Java Джеймс Гослінг заявив, що проблеми з множинним успадкуванням були однією з причин створення Java. Складнощі, властиві множинному успадкування, найвиразніше видно у проблемі алмазу. У задачі “ромб” батьківський клас A має два різні дочірні класи B та C; тобто дочірні класи B і C розширюють клас A. Кава-брейк #95.  Як вирішити проблему множинного успадкування в Java - 3Тепер ми створюємо новий дочірній клас D, який розширює як клас B, так і клас C. Зверніть увагу, що ми маємо множинне спадкування (D розширює B і C), ієрархічне успадкування ( B і C розширюють A) та багаторівневе успадкування (D розширює A, B та C). У проблемі ромба дочірні класи B і C успадковують метод від батьківського класу A. B і C перевизначають успадкований метод. Але нові методи B і C суперечать один одному. Остаточний дочірній клас D успадковує два незалежні та конфліктуючі методи від своїх кількох батьків B і C. Неясно, який метод класу D слід використовувати, тому виникає двозначність. Інші мови програмування ООП реалізують різні методи вирішення неоднозначності множинного успадкування.

Як вирішити проблему множинного успадкування в Java

Те, що множинне спадкування проблематичне, не означає, що воно марне. Є багато ситуацій, коли ви можете захотіти, щоб один клас мав функції кількох інших класів. Тільки подумайте про автомобіль Tesla Roadster, який ви купите, коли станете надзвичайно успішним розробником програмного забезпечення. Його технічні характеристики ґрунтуються як на класі спортивних автомобілів, так і на класі електромобілів. Ще один приклад: браузер, через який ви читаєте цю статтю. У ньому є функції із класу рішень для забезпечення конфіденційності даних в інтернеті та із загального класу інтернет-браузерів. Але ви не можете розширити кілька класів Java. То як же ця мова справляється з проблемою множинного спадкування? Java використовує структури, які називаються інтерфейсами. Інтерфейси - це абстрактні типи, які визначають поведінку для реалізації класами. Оскільки вони абстрактні, інтерфейси не містять докладних інструкцій щодо їхньої поведінки. Натомість класи надають конкретні реалізації поведінки інтерфейсу. Інтерфейси мають кілька визначальних характеристик:
  • На відміну від класів, ви не створюєте екземпляри інтерфейсів. Натомість класи реалізують інтерфейси.
  • Інтерфейси містять лише загальнодоступні визначення констант та заголовки методів.
  • Інтерфейси можуть розширювати лише інші інтерфейси, але з класи.
  • Інтерфейси можуть розширювати кілька інтерфейсів, а класи можуть реалізовувати кілька інтерфейсів.
Тепер ми можемо ефективно охвабони проблему ромба за допомогою інтерфейсів. Згадуючи, що тільки інтерфейси можуть розширювати лише інші інтерфейси і будь-який клас, якому потрібно кілька характеристик успадкування, має реалізовувати кілька інтерфейсів, ми можемо перевизначити класи проблем з ромбами. Те, що раніше було класами A, B і C, тепер стає інтерфейсами A, B і C. Інтерфейси B і C, як і раніше, розширюють інтерфейс A, але в жодному з цих інтерфейсів немає конкретних функцій, лише певні поведінки. Клас D залишається класом, який відповідає за конкретну реалізацію поведінки, виявленої в інтерфейсах B та C. Зверніть увагу на одну ключову відмінність: клас D не розширює інтерфейси B та C. Натомість він їх реалізує. Таким чином, у вас фактично немає множинного успадкування. Натомість ви просто переосмислабо проблему.

Висновок

Розуміння успадкування необхідне будь-якому ефективному Java-розробнику. Також не менш важливо знати обмеження успадкування та вбудований обхідний шлях Java для традиційних проблем із множинним успадкуванням. Вивчення того, як створювати інтерфейси для відтворення ефектів множинного успадкування Java, підвищить вашу ефективність і можливості найму.
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ