A többszörös öröklődés az objektumorientált programozási nyelvek egy része által támogatott tulajdonság , amikor egy osztálynak több szuperosztálya is lehet (közvetlen szülőosztály), az interfészek számos programozási nyelvben támogatják a többszörös öröklődést. Ez a fogalom az "egyszerű (vagy egyszeri) öröklődés " ( angolul single inheritance ) kiterjesztése, amelyben egy osztály csak egy szuperosztályból örökölhet.
A többszörös öröklődést támogató nyelvek a következők: Io , Eiffel , C++ , Dylan , Python , néhány JavaScript osztály implementáció (pl. dojo .declare ), Perl 6 , Curl , Common Lisp (a CLOS -nak köszönhetően ), OCaml , Tcl (az Incrementalnak köszönhetően) Tcl ) [1] , valamint Object REXX ( mixin osztályok használata miatt ).
A többszörös öröklődés lehetővé teszi egy osztály számára, hogy sok más osztálytól örököljön funkcionalitást, például egy osztály StudentMusicianörökölhet osztályból Person, osztályból Musicianés osztályból Worker, amelyek rövidítése a következőképpen lehetséges:
StudentMusician : Person, Musician, Worker.A többszörös öröklődés bizonytalansága, mint a fenti példában, akkor fordul elő, ha például egy osztály az és Musicianosztályokból örökli , az osztály pedig a ; hasonló helyzetet rombusz alakú öröklődésnek nevezünk . Így a következő szabályokat kapjuk: PersonWorkerWorkerPerson
Dolgozó : Személy Zenész : Személy, Dolgozó Hallgató Zenész: Személy, Zenész, DolgozóHa a fordító a StudentMusician osztályt nézi, akkor tudnia kell, hogy az osztályok jellemzőit kombinálni kell-e, vagy külön kell-e lenniük. Például logikus lenne a Személy osztály „életkorát” (életkorát) a StudentMusician osztályhoz csatolni. Egy személy életkora nem változik, ha személynek (személynek), dolgozónak (munkásnak) vagy zenésznek (zenésznek) tekinti. Teljesen logikus lenne azonban a „Név” tulajdonság elkülönítése a Személy és a Zenész osztályokban, ha a valódi nevüktől eltérő művésznevet használnak. Az egyesülési és felosztási opciók tökéletesen érvényesek a saját környezetükben, és csak a programozó tudja, hogy melyik opció a megfelelő a tervezett osztályhoz.
A nyelvek többféleképpen kezelhetik az ilyen beágyazott öröklődési problémákat, például:
A Smalltalk , a C# , az Objective-C , a Java , a Nemerle és a PHP nem teszi lehetővé a többszörös öröklődést, ami sok bizonytalanságot elkerül. A Smalltalkon kívül azonban lehetővé teszik az osztályok számára több interfész megvalósítását . Ezenkívül a PHP és a Ruby lehetővé teszi a többszörös öröklődés emulálását mixinek használatával (jellemzők a PHP-ben és mixinek a Rubyban), amelyek az interfészekhez hasonlóan nem teljes értékű osztályok. Az interfészek többszörös öröklése lehetővé teszi a korlátozott képességek kiterjesztését.
A többszörös öröklődést a következő problémák miatt kritizálták egyes nyelveken, különösen a C++ nyelven:
A többszörös öröklődés a C++/Java-stílusú konstruktorokkal rendelkező nyelveken súlyosbítja a konstruktor öröklődésének és a konstruktor sorozatok problémáját, így karbantarthatósági és bővíthetőségi problémákat okoz ezeken a nyelveken. A jelentősen eltérő konstrukciós módszerekkel öröklődő kapcsolatokban lévő objektumokat meglehetősen nehéz megvalósítani a konstruktor sorozat paradigmáján belül.
Vannak azonban olyan nyelvek, amelyek kezelik ezeket a technikai jellemzőket (pl. Eiffel ).
Van olyan vélemény, hogy a többszörös öröklődés hibás fogalom, amelyet rossz elemzés és tervezés generál. Különösen a következő tervezési lehetőség érvényes a fenti példára. A Személy osztály a Profession osztály egy vagy több objektumát tartalmazza. A Diák és a Zenész osztályok a szakmából öröklődnek. Így a StudentMusiciant a Személy osztály egy objektuma fogja képviselni, amely a Diák és a Zenész osztály objektumait tartalmazza. Formálisan a többszörös öröklődés visszafejthető egy olyan osztály bevezetésével, amely azon osztályok "metaosztálya", amelyekből többszörös öröklődés következik be. A fenti példában egy ilyen metaosztály a Profession – egy szakma.