Java on olio-ohjelmointikieli, jonka avulla kehittäjät voivat luoda monimutkaisia ohjelmistojärjestelmiä. Yksi Javan avainominaisuuksista on periytyminen, jonka avulla luokat voivat periä ominaisuuksia ja menetelmiä muilta luokilta. Javassa luokka voi laajentaa vain yhtä pääluokkaa kerrallaan, mutta rajapintojen avulla on mahdollista saavuttaa useita perinnöllisiä käyttäytymismalleja. Tässä artikkelissa tutkimme kuinka laajentaa useita Java-luokkia ja tarjota esimerkkiohjelmia tulosteilla.
Useiden luokkien laajentaminen Javassa
Java ei salli luokan laajentaa useita luokkia suoraan. Syynä tähän on välttää timanttiongelmaa, joka syntyy, kun luokka perii kahdesta luokasta, joilla on yhteinen superluokka. Tämän ongelman välttämiseksi Java sallii luokan toteuttaa useita rajapintoja, jotka voivat saavuttaa samanlaisia toimintoja.
Käyttöliittymä on kokoelma abstrakteja menetelmiä, jotka määrittelevät luokan käyttäytymisen. Toisin kuin luokat, rajapintoja ei voi ilmentää, mutta ne voidaan toteuttaa luokittain. Toteuttamalla rajapinnan luokka voi periä ominaisuuksia ja menetelmiä useilta rajapinnoilta. Sen avulla luokka voi saavuttaa useita perinnöllisiä käyttäytymismalleja ilman timanttiongelmaa. Laajentaaksemme useita Java-luokkia meidän on luotava käyttöliittymä, joka sisältää pääluokkien ominaisuudet ja menetelmät. Toteutusluokka voi sitten toteuttaa rajapinnan ja periä yläluokkien ominaisuudet ja menetelmät. Katsotaanpa esimerkkiä ymmärtääksemme paremmin tätä käsitettä.
sanakirjan alustus c#
Useiden luokkien laajentaminen Javassa
Tässä esimerkissä luomme kolme luokkaa: Eläin, Nisäkäs ja Matelija. Luomme sitten Omnivore-nimisen käyttöliittymän, joka laajentaa Animal- ja Mammal-luokkia. Lopuksi luomme luokan nimeltä Platypus, joka toteuttaa Omnivore-rajapinnan.
Animal-luokka sisältää menetelmän nimeltä 'syö', joka tulostaa 'Eläin syö'. Nisäkäsluokka laajentaa Animal-luokkaa ja sisältää menetelmän nimeltä 'drinkMilk', joka tulostaa 'Mammal is drinking milk'. Matelija-luokka laajentaa myös Animal-luokkaa ja sisältää menetelmän nimeltä 'layEggs', joka tulostaa 'Matelija munii'.
Tässä on Animal-luokan koodi:
public class Animal { public void eat() { System.out.println('Animal is eating.'); } }
Tässä on nisäkäsluokan koodi:
public class Mammal extends Animal { public void drinkMilk() { System.out.println('Mammal is drinking milk.'); } }
Tässä on matelija-luokan koodi:
Nimeä hakemisto uudelleen linux
public class Reptile extends Animal { public void layEggs() { System.out.println('Reptile is laying eggs.'); } }
Luodaan nyt Omnivore-käyttöliittymä, joka laajentaa Animal- ja Mammal-luokkia:
public interface Omnivore extends Animal, Mammal { public void eatPlants(); }
Lopuksi luodaan Platypus-luokka, joka toteuttaa Omnivore-käyttöliittymän:
public class Platypus implements Omnivore { public void eat() { System.out.println('Platypus is eating.'); } public void drinkMilk() { System.out.println('Platypus is drinking milk.'); } public void eatPlants() { System.out.println('Platypus is eating plants.'); } }
Tässä esimerkissä Platypus-luokka toteuttaa Omnivore-rajapinnan, joka laajentaa Animal- ja Mammal-luokkia. Siksi Platypus-luokka perii sekä Animal- että Mammal-luokkien ominaisuudet ja menetelmät.
Testataan ohjelmaamme luomalla esiintymä Platypus-luokasta ja kutsumalla sen menetelmiä:
Yhdistä lajittelu
public class Main { public static void main(String[] args) { Platypus p = new Platypus(); p.eat(); p.drinkMilk(); p.eatPlants(); } }
Lähtö:
Platypus is eating. Platypus is drinking milk. Platypus is eating plants.
Kuten näemme, Platypus-luokka pystyy perimään sekä Animal- että Mammal-luokkien ominaisuudet ja menetelmät toteuttamalla Omnivore-rajapinnan. Tämän avulla voimme saavuttaa useita perinnöllisiä käyttäytymismalleja Javassa.
Milloin käyttää usean periytymisen kaltaista käyttäytymistä Javassa
Vaikka Javassa on mahdollista saavuttaa useita perinnöllisiä käyttäytymismalleja rajapintojen avulla, se ei ole aina välttämätöntä tai toivottavaa. Itse asiassa monet kehittäjät väittävät, että moninkertainen periytyminen voi tehdä koodista monimutkaisempaa ja vaikeampaa ylläpitää. Siksi on tärkeää harkita huolellisesti, tarvitaanko moninkertaista periytymistä muistuttavaa toimintaa ohjelmallesi.
Eräs tilanne, jossa useat perinnölliset toiminnot voivat olla hyödyllisiä, on silloin, kun sinun on yhdistettävä toimintoja useista lähteistä. Jos sinulla on esimerkiksi kaksi luokkaa, jotka tarjoavat erityyppisiä toimintoja, saatat haluta yhdistää ne yhdeksi luokkaksi, joka perii molemmista. Tässä tapauksessa molempia luokkia laajentavan rajapinnan toteuttaminen voi olla hyvä ratkaisu. Toinen tilanne, jossa useista periytymisen kaltaisista toimista voi olla hyötyä, on, kun työskentelet kolmannen osapuolen kirjastojen kanssa, jotka käyttävät perintöä laajasti. Jos sinun on laajennettava useita kolmannen osapuolen luokkia, rajapintojen käyttöönotto voi olla hyvä tapa saavuttaa tämä luomatta monimutkaisia perintöhierarkioita.
Javassa ei ole mahdollista laajentaa suoraan useita luokkia. On kuitenkin mahdollista saavuttaa useita perinnöllisiä käyttäytymismalleja toteuttamalla rajapintoja, jotka laajentavat useita luokkia. Tämä sallii luokan periä ominaisuuksia ja menetelmiä useilta pääluokilta ilman timanttiongelmaa, joka voi syntyä suorassa moniperinnössä. Vaikka moniperinnön kaltainen käyttäytyminen voi olla hyödyllistä tietyissä tilanteissa, on tärkeää harkita huolellisesti, onko se tarpeen ohjelmallesi. Monissa tapauksissa käyttöliittymien ja koostumuksen käyttö voi olla parempi ratkaisu useiden eri lähteiden toimintojen yhdistämiseen.