Sisällys JAVA-OHJELMOINTI Osa 6: Periytyminen ja näkyvyys Periytyminen (inheritance) Näkyvyys (visibility) Eero Hyvönen Tietojenkäsittelytieteen laitos Helsingin yliopisto 13.10.2000 E. Hyvönen: Java Osa 6 2 Luokkahierarkia Periytyminen (inheritance) Luokat muodostavat käsitehierarkian Yliluokka (superclass) <-> Aliluokka (subclass) Aliluokalla on aina vain yksi yliluokka Aliluokka oletusarvoisesti perii (inherit) automaattisesti yliluokan muuttuja- ja metodimäärittelyjä Etu: Määrittelyjä ei tarvitse toistaa aliluokassa (Luokka voi periä myös ns. rajapintamäärittelyjä (interface).) Esitellään myöhemmin 13.10.2000 E. Hyvönen: Java Osa 6 4 Kaikilla luokilla on ainakin yksi yliluokka Object Paitsi luokalla Object, joka edustaa hierarkian huippua. Object = kaikkien olioiden äiti Object-luokasta periytyy: String tostring() Olion arvo merkkijonona, määritellään yleensä uudelleen aliluokissa print(ln)(object o)-metodit käyttävät tätä metodia tulostuksessa! Class getclass() int hascode() Object clone() Class olio sisältää tietoa oliosta Olion hakautusarvo (hash code), voi käyttää indeksoinnissa Luo kloonatusti kopion 13.10.2000 E. Hyvönen: Java Osa 6 5 Yliluokka ilmaistaan extends -ilmauksella classmäärittelyssä: class Aliluokka extends Yliluokka { Object-yliluokkaa ei erikseen ilmaista. Periminen on keskeinen tiedon ja proseduurien jäsentelyn väline Helpottaa ohjelmien kirjoittamista, Määrittelyjä ei tarvitse toistaa Helpottaa ohjelmien ylläpito Määrittelyt vain kerran oikeassa yhteydessä 13.10.2000 E. Hyvönen: Java Osa 6 6 1
Metodien korvaaminen (override) class Henkilo { String Nimi; int syntymävuosi; class Opiskelija extends Henkilo { String opiskelijatunnus; // Vain Opiskelijaan liittyvät lisäytiedot int aloitusvuosi;. String opiskelupaikka() { // Metodit. class YliopistoOpiskelija extends Opiskelija { Kurssi [] suoritetutkurssit;... class MuuntoOpiskelija extends YliopistoOpiskelija { Kurssi [] muuntohyvaksiluku; 13.10.2000 E. Hyvönen: Java Osa 6 7 Aliluokka voi antaa perimälleen ominaisuudelle uusia tulkintoja kuormittamalla (overload) Määritellään samanniminen metodi, mutta eri parametreille Aliluokka voi myös määritellä kokonaan uuden sisällön korvaamalla (override) Määritellään täsmälleeen sama metodi uudelleen, jolloin yliluokan määrittely korvaantuu uudella. : Kaikki luokat perivät olion tulostavan tostring metodin Objectluokalta. Se voidaan määritellä uudestaan esim. Henkilo-luokalle. print(ln)-komennot tulostavat sitten automaattisesti tämän mukaisesti. 13.10.2000 E. Hyvönen: Java Osa 6 8 private-määre Ilmentymämetodi voi korvata vain ilmentymämetodin. Luokkametodi voi korvata vain luokkametodin. Vaikka yliluokan metodi korvataan, voidaan myös korvattuun metodiin tarvittaessa viitata ilmauksella super. Käytetään kuten this -ilmausta. Esimerkiksi: super.metodi( ); Private-etumääre estää periytymisen private-muuttujia ei voi käyttää aliluokassa private int salainen = 3; // Ilmentymämuuttuja private static int salainen = 3; // Luokkamuuttuja Vastaavasti private metodeja ei voi kutsua aliluokissa private int salasana() { ; private static int salasana() { ; 13.10.2000 E. Hyvönen: Java Osa 6 9 13.10.2000 E. Hyvönen: Java Osa 6 10 final-määre final-määreen merkitys final-määreellä voidaan rajoittaa luokkahierarkiaa ja periytymistä Määre voidaan asettaa: luokkamäärittelyn eteen (class) final class Lehti { metodin määrittelyn eteen final void laske() { muuttujan määrittelyn eteen final int tulos; Merkitys Luokka Luokalle ei voi määritellä aliluokkia. Metodi Metodia ei voi korvata aliluokissa. Muuttuja Arvoa ei voi muuttaa alkuasetuksen jälkeen. 13.10.2000 E. Hyvönen: Java Osa 6 11 13.10.2000 E. Hyvönen: Java Osa 6 12 2
Monimuotoisuus (polymorfismi) Jos näitä ehtoja rikotaan ohjelmassa, Java-kääntäjä antaa automaattisesti virheilmoituksen. Esimerkiksi final -määreisen luokan aliluokan määrittely. final -määreisen metodin uudelleen määrittäminen aliluokassa. funal -määreisen muuttuja arvon muuttaminen. Yliluokan muuttujalle voidaan antaa arvoksi aliluokan olio. Esimerkiksi: Object x; x = new Henkilo("Onni Opiskelija"); Kun muuttujan kautta kutsutaan metodia voisi valinta tapahtua kahdella tavalla: Muuttujan tyypin perusteella (edellä Object) Muuttujat arvon oli olion tyypin perusteella (edellä Henkilo) Javassa valinta tapahtuu dynaamisesti arvon ajonaikaisen, ei käännösaikaisen tyypin perusteella. Tätä kutsutaan monimuotoisuudeksi (polymorfism) 13.10.2000 E. Hyvönen: Java Osa 6 13 13.10.2000 E. Hyvönen: Java Osa 6 14 Kentän peittäminen class Kissa { String nimi; public Kissa(String nimi) {this.nimi=nimi; public String tostring() { return nimi; ----- metodi jossain toisessa luokassa ---... Kissa kisu = new Kissa("Kurnauskis"); Object objekti = kisu; System.out.println(kisu); System.out.println(objekti);... // Tulostuu Kurnauskis // Kissan tostring metodi löytyy, //Tulostuu Kurnauskis Myös yliluokalta perityn kentän (muuttujan) voi korvata eli peittää (hide) uudella määrittelyllä. 13.10.2000 E. Hyvönen: Java Osa 6 15 13.10.2000 E. Hyvönen: Java Osa 6 16 Olio metodin parametrina ja arvona Kun metodin parametri on viittaustyyppiä: Metodia kutsuttaessa parametrin todelliseksi arvoksi tulee jokin ko. luokkaa tai sen aliluokkaa oleva olio. Esimerkiksi Object-tyyppiselle parametrille voi antaa arvoksi minkä luokan tahansa olion. Metodille välittyy vain viite ko. olioon, ei kopiota oliosta. Viitattuun olioon tehdyt muutokset jäävät voimaan metodin suorituksen jälkeenkin. Myös metodin arvona palautuu vain viite. Kertausta Mitä eroa on käsitteillä "override" ja "overload"? Mitä tarkoittaa, jos metodilla on final-määre? luokalla on final määre? Mitä on polymorfismi? 13.10.2000 E. Hyvönen: Java Osa 6 17 13.10.2000 E. Hyvönen: Java Osa 6 18 3
Konstruktorit ja periytyminen Konstruktorit ovat poikkeus periytymisessä Eivät koskaan periydy aliluokalle Konstruktori suoritetaan seuraavasti: Valitaan kuormitetuista konstruktoreista kutsuun sopiva. Konstruktorin 1. lauseessa voidaan kutsua yliluokan konstruktoreita erityisen super(parametrit) kutsun avulla. Jos mitään yliluokan konstruktoria ei itse kutsuta, kutsuu Java yliluokan parametritonta kontruktoria ilmauksella super(). Tällä taataan perittyjen kenttien alustus ennen lapsiluokan konstruktorin laskentaa. Yliluokan konstruktoreita voidaan kutsua näin ainoastaan aliluokan konstruktorista käsin. (super-muuttujaa voidaan käyttää yleisesti.) Luokan kentät alustetaan. Suoritetaan konstruktorin muut lauseet. 13.10.2000 E. Hyvönen: Java Osa 6 19 class Piste { int x, y; // Kentät periytyvät public Piste(int x, int y) { this.x=x; this.y=y; // konstruktori public String tostring() { return "("+ x + "," + y+")"; class VariPiste extends Piste{ private int väri; public VariPiste(int x, int y, int väri) { super(x,y); // Kantaluokan 2-parametrinen konstr. this.väri=väri; public String tostring() { return "("+ x + "," + y+")" +"väri:" + väri; // Tai: public String tostring() {return super.tostring()+"väri:"+väri; 13.10.2000 E. Hyvönen: Java Osa 6 20 Metodien ja muuttujien näkyvyys Näkyvyys (visibility) Näkyvyydellä (visibility) tarkoitetaan muuttujien ja metodien yhteydessä kahta asiaa: Periytyminen (inheritance) kertoo, voidaanko yliluokan muuttujia ja metodeja käyttää aliluokassa ikäänkuin ne olisivat siellä määritelty. Viitattavuus (access) kertoo, missä muissa luokissa luokan muuttujaan/metodiin voidaan viitata. Kaikkiin luokan omiin muuttujiin/metodeihin voidaan viittata ko. luokan sisällä, muttei välttämättä toisten luokkien muuttujiin/metodeihin. 13.10.2000 E. Hyvönen: Java Osa 6 22 Näkyvyyden säätely Oletusarvoisesti "pakkausnäkyvyys" Muuttujat/metodit periytyvät luokan kaikkiin aliluokkiin samassa pakkauksessa. Muuttujia/metodeja voidaan käyttää (viittaus/kutsu) saman pakkauksen kaikista luokista. Näkyvyyttä voidaan kuitenkin säädellä näkyvyysmääreillä (visibility modifier): public protected private Näkyvyysmääreet kirjoitetaan muuttujaesittelyn tai metodimäärittelyn eteen: private double hinta; public final int MAKSIMI; protected double laske(double x) { public static void main(strinf[] args) { 13.10.2000 E. Hyvönen: Java Osa 6 23 13.10.2000 E. Hyvönen: Java Osa 6 24 4
Muuttujien ja metodien näkyvyys Määre Ei määrettä (oletus) public protected private Merkitys Periytyminen kaikkiin aliluokkiin, jotka ovat samassa pakkauksessa. Kutsuttavissa/viitattavissa saman pakkauksen sisällä. Periytyminen kaikkiin aliluokkiin (myös eri pakkauksiin). Kutsuttavissa/viitattavissa kaikkialta. Periytyminen kaikkiin aliluokkiin (myös eri pakkauksiin). Kutsuttavissa/viitattavissa vain saman pakkauksen sisällä. Ei periydy aliluokkiin (mutta on määritelty näille, ks. myöhemmin). Kutsuttavissa/viitattavissa vain omassa luokassa. J. Lewis, W. Loftus, Appendix F, p. 599 (Kurssimapissa on yhteenveto). 13.10.2000 E. Hyvönen: Java Osa 6 25 13.10.2000 E. Hyvönen: Java Osa 6 26 Konstruktorien näkyvyys Konstruktorillakin voi olla näkyvyysmääre. Koska konstruktorit eivät periydy ei taulukon periytymissääntöjä ei sovelleta. Muuten näkyvyys on kuten metodeilla: ei määrettä: Voi kutsua vain samasta pakkauksesta. public: Voi kutsua kaikkialta. protected: Voi kutsua vain samasta pakkauksesta. private: Voi kutsua vain samasta luokasta. Periytyminen ja viitattavuus Kun luokka perii muuttujan tai metodin niihin voidaan viitata suoraan aliluokasta. Ikäänkuin ne olisi paikallisesti määritelty. Myös sellaiset muuttujat/metodit, jotka eivät periydy on määritelty aliluokille! Niihin voidaan kuitenkin viitata vain epäsuorasti. Esimerkiksi yliluokan periytyvä metodi voi viitata yliluokan private-tyyppiseen kenttään tai kutsua private-tyyppistä metodia. 13.10.2000 E. Hyvönen: Java Osa 6 27 13.10.2000 E. Hyvönen: Java Osa 6 28 class Piste { private int x, y; // Kentät yksityisiä, eivät periydy public Piste(int x, int y) { this.x=x; this.y=y; // konstr. public String tostring() { return "("+ x + "," + y+")"; class VariPiste extends Piste{ private int väri; public VariPiste(int x, int y, int väri) { super(x,y); // Kantaluokan 2-parametrinen konstr. this.väri=väri; public String tostring() { return super.tostring() +"väri:" + väri; // super.tostring() tulostaa "(x, y)" vaikkeivat x ja y periydy // eikä niihin voida suoraan luokasta viitata! 13.10.2000 E. Hyvönen: Java Osa 6 29 Piste-luokan x ja y ovat yksityisiä (private) Eivät periydy eli eivät ole viitattavissa Väripisteluokassa Väripiste-luokan olioille On kuitenkin olemassa x- ja y-kentät arvoineen, vaikkei niihin voida ko. luokassa viitata suoraan. Yliluokan metodit voivat käyttää näitä muuttujia/arvoja. Arvoihin voidaan viitata myös aliluokasta epäsuorasti supermuuttujan kautta (esim. super.x). 13.10.2000 E. Hyvönen: Java Osa 6 30 5
Periytyminen vs. määrittely Yliluokan (ilmentymä)muuttujat (myös private) on aina määritelty/olemassa aliluokille Periytymisessä on kyse näkyvyydestä, ts. siitä voidaanko yliluokan muuttujiin viitata aliluokassa Luokkien näkyvyys Myös luokalla on näkyvyys Oletusarvoisesti (ei määrettä) luokkaan voidaan viitata saman pakkauksen sisällä (pakkausnäkyvyys). public -etumääre laajentaa luokan näkyvyyden kaikkialle. protected- ja private-määreillä ei ole luokan yhteydessä tulkintaa. 13.10.2000 E. Hyvönen: Java Osa 6 31 13.10.2000 E. Hyvönen: Java Osa 6 32 Kertausta Miten näkyvyys ilmaistaan määrittelyssä? Miten periytyvyys eroaa viitattavuudesta? Mitä merkitsevät alla olevat määreet muuttujien ja metodien yhteydessä? public protected private Millaisia näkyvyysasteita voi määritellä luokille? Mitä ne merkitsevät? Periytymisen ja määrittelyn suhde Javassa? 13.10.2000 E. Hyvönen: Java Osa 6 33 Lisätietoja Arto Wikla: Ohjelmoinnin perusteet Java-kielellä, OtaDATA, 1998. John Lewis, William Loftus: Java Software Solutions, Addison-Wesley, 1998. 13.10.2000 E. Hyvönen: Java Osa 6 34 6