Moniperintä (engl. Multiple inheritance) on olio-ohjelmointikielen ominaisuus laajentaa toimintoja useasta luokasta perinnällä. Moniperintä mahdollistaa uuteen luokkaan periyttämisen useista kantaluokista. Moniperintä on hyödyllistä tilanteessa, jossa luokka Lepakko sisältää Lentävä eläin - ja Nisäkäs-luokkien ominaisuudet.

Kaikki perintää tukevat ohjelmointikielet eivät tue moniperintää tai asettavat rajoituksia sen käytölle.

Moniperinnän tarpeellisuudesta on kiistelty useita vuosia. Eräissä tapauksissa sen riskit katsotaan liian suuriksi verrattuna sen hyötyihin.[1]

Ohjelmointitason ongelmat voidaan ratkaista ilmankin moniperintää, mutta sen käyttö voi myös helpottaa toteutuksen tekemistä riippuen ratkaistavan ongelman laadusta.[2]

Olio-ohjelmoinnissa (engl. Object-oriented programming, OOP) periytyminen kuvaa kahden luokan välistä suhdetta, jossa yksi luokka (lapsiluokka) on toisen luokan (emoluokka) alaluokka. Lapsi perii vanhemman menetelmät ja attribuutit, mikä mahdollistaa jaetun toiminnallisuuden. Voidaan esimerkiksi luoda muuttujaluokka Nisäkäs, jolla on ominaisuuksia, kuten syöminen, lisääntyminen jne.; määritä sitten lapsiluokan Kissa, joka perii nämä ominaisuudet ilman, että niitä tarvitsee erikseen ohjelmoida ja lisää samalla uusia ominaisuuksia, kuten hiirten jahtaaminen.

Usean periytymisen ansiosta ohjelmoijat voivat käyttää useampaa kuin yhtä täysin ortogonaalista hierarkiaa samanaikaisesti, esimerkiksi sallimalla luokan Kissa periä luokista Sarjakuvahahmot, Lemmikki ja Nisäkäs sekä käyttää ominaisuuksia kaikkien näiden luokkien sisällä.

Virtuaalinen moniperintä

muokkaa
 
Timanttiongelman luokkakaavio

Niin sanotussa timanttimuodon moniperinnässä voi tulla vastaan tilanne, jossa periytynyt luokka saa kaksi toteutusta samasta kantaluokassa olevasta toteutuksesta. Yksiselitteinen viittaus perittyyn muuttujaan tai metodiin vaikeutuu vastaavassa tilanteessa.

Niin kutsuttu timanttiongelma on ongelma, joka syntyy, kun kaksi luokkaa B ja C perivät A:sta ja luokka D perii sekä B:stä että C:stä. Jos on olemassa menetelmä A:ssa, jonka B ja C ovat korvanneet (engl. override) ja D ei korvaa sitä, niin minkä menetelmän version D perii: B:n vai C:n version?

Sitä kutsutaan timanttiongelmaksi luokan periytymiskaavion muodon vuoksi tässä tilanteessa. Tässä tapauksessa luokka A on ylhäällä, sekä B että C erikseen sen alla, ja D yhdistää nämä kaksi alareunaa muodostaen “timantin”.

C++ ratkaisee ongelman tukemalla virtuaalista moniperintää, jonka avulla periytyy vain yksi toteutus yhteisen kantaluokan jäsenistä.[3][4]

Toteutukset

muokkaa

Moniperintää tukevat kielet kuten C++, Eiffel, OCaml ja Scala.

Rajattua moniperintää (interface eli rajapintaperintää) tukevat kielet kuten Ada, C# ja Java.

JavaScript käyttää perimisen toteuttamiseen prototyyppejä.

Lähteet

muokkaa
  1. Multiple Inheritance Considered Useful Dr Dobbs. Viitattu 7.2.2017.
  2. Inheritance — Multiple and Virtual Inheritance isocpp.org. Viitattu 7.2.2017.
  3. Solving the Diamond Problem with Virtual Inheritance Cprogramming.com. Viitattu 8.2.2017.
  4. Inheritance — Multiple and Virtual Inheritance isocpp.org. Viitattu 8.2.2017.