Множинне успадкування

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до: навігація, пошук

Множи́нна спадко́вість — властивість деяких об'єктно орієнтовних мов програмування, в яких класи можуть успадкувати поведінку і властивості більш ніж від одного суперкласу (безпосереднього батьківського класу). Це відрізняється від простого спадкування, у випадку якого клас може мати тільки один суперклас.

Мови програмування з підтримкою множинного спадкування: Eiffel, C++, Dylan, Python, Perl, Curl, Common Lisp (завдяки CLOS), OCaml, Tcl (завдяки Incremental Tcl)[1] та Object REXX (завдяки використанню класів домішок).

Огляд[ред.ред. код]

Множинна спадковість дозволяє класу успадковувати функціональність від декількох інших класів, так як дозволяє класу StreetMusician успадковуватись від класів Human, Musician Worker. Це можна скоротити як StreetMusician : Human, Musician, Worker.

При множинному спадкуванні в попередньому прикладі може винукнути невизначенність, якщо, наприклад, клас Musician походить від Human і Worker, а клас Worker також походить від Human. В такому випадку кажуть про присутність ромбоподібного спадкування. Таким чином отримуємо:

Worker          :  Human
Musician        :  Human, Worker
StreetMusician :  Human, Musician, Worker

Якщо компілятор переглядає клас StreetMusician, йому необхідно знати, коли об'єднувати однакові властивості, а коли тримати їх окремо. Наприклад, має сенс об'єднати властивості Age класу Human в StreetMusician. Вік людини не змінюється незалежно від того, чи ми розглядаємо її як музиканта, працівника або як людину загалом. З іншого боку, ім'я може бути як сценічним псевдонімом, так і справжнім ім'ям. Вибір об'єднати або відокремити покладається на програміста, який має знати, що саме є правильним при розробці певного класу.

Різні мови обробляють повторюване наслідування різними шляхами.

  • Eiffel дозволяє програмісту явно об'єднати або розділити властивості успадковані від суперкласів. Eiffel автоматично об'єднує властивості, якщо вони мають однакові імена та реалізації. Програміст має змогу перейменувати успадковані властивості, щоб розділити їх. Eiffel також дозволяє явне повторюване спадкування, таке як A: B, B.
  • C++ вимагає явної вказівки, з якого батьківського класу треба використати дану властивість, тобто "Worker::Human.Age". C++ на відміну від Eiffel не дозволяє явного повторюваного спадкування через відсутність можливості вказати, який з суперкласів треба використовувати. C++ підтримує можливість уникнення неоднозначності через створення єдиного екземпляра батьківського класу через використання механізму віртуальної спадковості (тобто "Worker::Human" і "Musician::Human" будуть вказувати на один і той самий об'єкт).
  • Perl використовує список класів для спадкування як впорядкований список. Компілятор використовує метод знайденим першим за допомогою пошуку в глибину серед списку суперкласів або C3 лінеаризації ієрархії класів. Різні розширення забезпечують альтернативні побудови. Python має таку саму структуру, але, на відміну від Perl, містить це як частину синтаксису самої мови. В Perl і Python на семантику класу впливає порядок спадкування.

Smalltalk, C#, Objective-C, Object Pascal, Java, Nemerle, та PHP не підтримують множинної спадковості реалізації, і це дозволяє уникнути будь-якої неоднозначності. Однак всі вони, крім Smalltalk, надають класам можливість реалізувати декілька інтерфейсів.

Перевіркою на необхідність множинного спадкування може стати ситуація, коли після побудови структури класів кінцеві класи (листя) можна згрупувати в набори за різними ортогональними ознаками і ці набори між собою перетинаються, що може слугувати ознакою неможливості обійтися однією структурою спадкування, в якій існували б якісь проміжні класи з потрібною поведінкою.

Примітки[ред.ред. код]