12. Monimuotoisuus 12.1

Samankaltaiset tiedostot
12. Monimuotoisuus 12.1

Sisällys. 12. Monimuotoisuus. Johdanto. Alityypitys. Johdanto. Periytymismekanismi määrittää alityypityksen.

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

9. Periytyminen Javassa 9.1

9. Periytyminen Javassa 9.1

Sisällys. Mitä on periytyminen? Yksittäis- ja moniperiytyminen. Oliot ja perityt luokat. Periytymisen käyttö. 8.2

Mitä on periytyminen?

16. Javan omat luokat 16.1

Rajapinnasta ei voida muodostaa olioita. Voidaan käyttää tunnuksen tyyppinä. Rajapinta on kuitenkin abstraktia luokkaa selvästi abstraktimpi tyyppi.

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

Sisällys. 11. Rajapinnat. Johdanto. Johdanto

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

A) on käytännöllinen ohjelmointitekniikka. = laajennetaan aikaisemmin tehtyjä luokkia (uudelleenkäytettävyys)

15. Ohjelmoinnin tekniikkaa 15.1

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2

Sisällys. Metodien kuormittaminen. Luokkametodit ja -attribuutit. Rakentajat. Metodien ja muun luokan sisällön järjestäminen. 6.2

7. Oliot ja viitteet 7.1

Sisällys. JAVA-OHJELMOINTI Osa 6: Periytyminen ja näkyvyys. Luokkahierarkia. Periytyminen (inheritance)

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

Oliot viestivät metodeja kutsuen

Sisällys. 7. Oliot ja viitteet. Olion luominen. Olio Java-kielessä

Sisällys. 6. Metodit. Oliot viestivät metodeja kutsuen. Oliot viestivät metodeja kutsuen

15. Ohjelmoinnin tekniikkaa 15.1

14. Poikkeukset 14.1

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 27. lokakuuta 2009

7. Näytölle tulostaminen 7.1

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

Olio-ohjelmointi Javalla

Java-kielen perusteet

14. Poikkeukset 14.1

Java-kielen perusteet

4. Olio-ohjelmoinista lyhyesti 4.1

Taulukot. Jukka Harju, Jukka Juslin

Virtuaalifunktiot ja polymorfismi

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op)

4. Luokan testaus ja käyttö olion kautta 4.1

20. Javan omat luokat 20.1

Sisällys. 20. Javan omat luokat. Java API. Pakkaukset. java\lang

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2

Muusta kuin vesisioista

Mikä yhteyssuhde on?

2. Olio-ohjelmoinista lyhyesti 2.1

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. IV Periytyminen ja monimuotoisuus

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 16.3

Kooste. Esim. Ympyrän keskipiste voidaan ajatella ympyrän osaksi.

Rajapinta (interface)

Olio-ohjelmointi Syntaksikokoelma

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 15.3

17. Javan omat luokat 17.1

Sisällys. 15. Lohkot. Lohkot. Lohkot

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Rajapinnat ja sisäluokat

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

Sisällys. JAVA-OHJELMOINTI Osa 7: Abstrakti luokka ja rajapinta. Abstraktin luokan idea. Abstrakti luokka ja metodi. Esimerkki

Ohjelmointi 2 / 2010 Välikoe / 26.3

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

13. Loogiset operaatiot 13.1

Geneeriset luokat. C++ - perusteet Java-osaajille luento 6/7: Template, tyyppi-informaatio, nimiavaruudet. Geneerisen luokan käyttö.

1. Omat operaatiot 1.1

815338A Ohjelmointikielten periaatteet

Muuttujat ja kontrolli. Ville Sundberg

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Tietorakenneluokkia 2: HashMap, TreeMap

T Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

- Komposiittityypit - Object (Mukaanlukien funktiot) - Array. - Erikoisdatatyypit - null - undefined

Sisältö. 2. Taulukot. Yleistä. Yleistä

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä

Sisältö. 22. Taulukot. Yleistä. Yleistä

Antti-Jussi Lakanen Ohjelmointi 1, C# / kevät 2011

Kompositio. Mikä komposition on? Kompositio vs. yhteyssuhde Kompositio Javalla Konstruktorit set-ja get-metodit tostring-metodi Pääohjelma

Javan perusteita. Janne Käki

Metodien tekeminen Javalla

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

13. Loogiset operaatiot 13.1

17. Javan omat luokat 17.1

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Java-kielen perusteet

8. Näppäimistöltä lukeminen 8.1

Sisällys. 16. Lohkot. Lohkot. Lohkot

ITKP102 Ohjelmointi 1 (6 op)

Oliot ja tyypit. TIES542 Ohjelmointikielten periaatteet, kevät Antti-Juhani Kaijanaho. Jyväskylän yliopisto Tietotekniikan laitos

19. Olio-ohjelmointia Javalla 19.1

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

7/20: Paketti kasassa ensimmäistä kertaa

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

Sisällys. 19. Olio-ohjelmointia Javalla. Yleistä. Olioiden esittely ja alustus

Jypelin käyttöohjeet» Miten voin liittää törmäyksiin tapahtumia?

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

on ohjelmoijan itse tekemä tietotyyppi, joka kuvaa käsitettä

11. Javan valintarakenteet 11.1

Sisällys. 19. Unified Modeling Language (UML) Johdanto. Johdanto. Johdanto. Luokkakaavio:

lausekkeiden tapauksessa. Jotkin ohjelmointikielet on määritelty sellaisiksi,

Olio-ohjelmoinnissa luokat voidaan järjestää siten, että ne pystyvät jakamaan yhteisiä tietoja ja aliohjelmia.

Java kahdessa tunnissa. Jyry Suvilehto

Groovy. Niko Jäntti Jesper Haapalinna Group 31

2. Olio-ohjelmoinnin perusteita 2.1

Transkriptio:

12. Monimuotoisuus 12.1

Sisällys Johdanto. Periytymismekanismi määrittää alityypityksen. Viitteiden sijoitus ja vertailu. Staattinen ja dynaaminen luokka. Parametrinvälitys eräs monimuotoisuuden sovellus. Tyyppimuunnos. Rajapinnat ja alityypitys. 12.2

Johdanto Monimuotoisuus eli polymorfismi (polymorphism) on yleisesti sitä, että ohjelman tunnus voi tarkoittaa erilaisia asioita. Monimuotoisuus on monimuotoinen käsite. Metodien kuormitus ja korvaaminen eräänlaista monimuotoisuutta. Monimuotoisuus liittyy erityisen kiinteästi periytymiseen: Luokkahierarkia määrittelee alityypityksen, jossa kukin jälkeläinen edustaa alityyppiä ja kukin esi-isä ylityyppiä. Tarkastellaan jatkossa monimuotoisuutta Javakielen näkökulmasta. 12.3

Alityypitys Määritellään tyyppien yhteensopivuus (<:) hyvin vapaamuotoisesti luokkien periytymissuhteen avulla: Tyyppi T (luokka) on yhteensopiva itsensä kanssa. T <: T (refleksiivisyys). Alityyppi S (aliluokka) on yhteensopiva ylityyppinsä T (yliluokkansa) kanssa. S <: T. Alityyppi S (jälkeläinen) on yhteensopiva kaikkien ylityyppiensä Q (esi-isiensä) kanssa. Jos S <: T ja T <: Q, niin S <: Q, (transitiivisuus). Ylityyppi Q (esi-isä) ei ole yhteensopiva alityyppiensä T (jälkeläistensä) kanssa (antisymmetrisyys). 12.4

Alityypitys Esim. C Object Koska Object-luokka on A-, B-, C- ja D-luokkien esi-isä (Object > { A, B, C, D }), niin A-, B-, C- ja D-tyypit ovat yhteensopivia Object-tyypin kanssa. A B D Samoin koska A-luokka on B- ja C- luokkien esi-isä (A > { C, B }), niin B- ja C-tyypit ovat yhteensopivia A-tyypin kanssa. Toisaalta esimerkiksi A-tyyppi ei ole yhteensopiva B-tyypin kanssa, koska A-luokka ei ole B- luokan jälkeläinen. Huomaa myös, että esimerkiksi C- ja D-tyypit eivät sovi yhteen, koska niitä vastaavien luokkien välillä ei ole periytymissuhdetta. 12.5

Alityypitys Alityypityksen seurauksena viitteiden x (X-luokka) ja y (Y-luokka) sijoitus x = y; on sallittu, jos Y <: X eli X > Y. Alityyppi käy ylityyppiinsä. Esimerkki: Object o = null; A a = null; B b = null; C c = null; D d = null; // Oikeellisia sijoituksia. o = a; // A <: Object o = b; // B <: Object o = c; // C <: Object o = d; // D <: Object a = b; // B <: A a = c; // C <: A // Virheellisiä sijoituksia. a = o; // Object > A b = a; // A > B c = d; // ei periytymissuhdetta Vertailussa operadien oltava yhteensopivia, järjestyksellä ei ole väliä. 12.6

Alityypitys Viite ja siihen liittyvä olio voivat olla eri luokista, kunhan tyypit vain ovat sijoitusyhteensopivia. Viitteeseen voi liittyä viitteen luokan olioiden lisäksi myös olioita viitteen luokan jälkeläisluokista. Esim. Object o = null; o = new A(); Nisakas n = new Kissa(); Object p = new String(); 12.7

Staattinen ja dynaaminen luokka Erotetaan jatkossa viitteen luokka (staattinen luokka) ja olion perusluokka (dynaaminen luokka) toisistaan. Dynaaminen luokka vaihtelee staattisen luokan asettamissa rajoissa. Staattinen luokka on dynaamisen luokan yläraja. Object Staattinen luokka Object A B A // Oikein (Object > A) Object o = new A(); // Väärin (A > B) B p = new A(); B Dynaaminen luokka voi olla Object, A, B A, B B 12.8

Staattinen ja dynaaminen luokka Esimerkki Staattinen luokka Kissa molli = new Kissa(); Kissa Kissa Nisakas nisse = new Kissa(); Nisakas Kissa Object elain; elain = new Kissa(); Object Dynaaminen luokka Kissa elain = new Koira(); Koira // Tämä ei käänny, // koska Object > Kissa. Kissa mussu = new Object(); (Kissa) (Object) 12.9

Staattinen ja dynaaminen luokka Java näkee olion viitteen luokan (staattinen luokka) kautta: ilman tyyppimuunnosta käytettävissä ovat vain staattisen luokan piirteet. // Asetetaan kissaan // Nisakas-luokan viite. Nisakas nisse = new Kissa(); // Kissa ei osaa nyt esim. // kehrätä, koska staattinen // luokka on Nisakas. // Kääntäjä tuottaa virheen. nisse.kehraa(); nisse elossa, paino syo(), onkoiso() turkillinen vari, hanta aantele(string), kehraa() Object-kerros Elain-kerros Nisakas-kerros Kissa-kerros 12.10

Staattinen ja dynaaminen luokka Olio-ohjelmassa viitteeseen liittyvän olion tyyppi selviää usein vasta ohjelman ajon aikana. Tässä tapauksessa myös kutsuttavan metodin versio täytyy päätellä ajon aikana. Dynaamisesti ajon aikana tapahtuvaa metodikutsujen liittämistä metodeihin kutsutaan myöhäiseksi sidonnaksi. Proseduraalisissa ohjelmointikielissä aliohjelmien kutsut voidaan liittää aliohjelmien koodiin jo käännösaikana: kutsut ja määrittelyt sidotaan siis staattisesti (aikainen sidonta). 12.11

Parametrinvälitys Monimuotoisuutta hyödynnetään usein parametrinvälityksessä. Parametrin tyypiksi asetetaan jokin riittävän lähellä luokkahierarkian juurta oleva luokka, jolloin metodille voidaan antaa parametriksi jälkeläisluokkien viitteitä (ja olioita). public void rokota(nisakas n) { // Täällä rokotetaan // muun muassa // kissoja, koiria ja ihmisiä. } Kissa rontti = new Kissa(); // Toimii, koska Kissa <: Nisakas. rokota(rontti); 12.12

Parametrinvälitys instanceof-operaattorilla voidaan selvittää parametriin liittyvän olion luokka, jos tiedetään mitä luokkia oliot edustavat. Yleisesti: viite instanceof LuokanNimi Operaattori palauttaa totuusarvon true, mikäli viite osoittaa olioon, jonka luokka (tai esi-isä) on nimeltään LuokanNimi. public void rokota(nisakas n) { if (n instanceof Kissa) { } // Täällä rokotetaan kissa. else if (n instanceof Ihminen) { // Täällä rokotetaan ihminen Huom! Operaattorin runsas käyttö ei ole suotavaa, koska yleensä pyritään mahdollisimman erillisiin luokkiin. 12.13

Tyyppimuunnos Eksplisiittiset tyyppimuunnokset ()-operaattorilla ovat tuttuja jo alkeistyyppien yhteydestä. Esim. // 1.25 double osamaara = 5 / (double)4; // Väliaikainen muunnos, // osamäärän palaa arvoon 1.25 // tämän lauseen jälkeen System.out.println((int)osamaara); // 1 // Tallennetaan muunnoksen tulos. int kokonaisosa = (int)osamaara; // 1 12.14

Tyyppimuunnos Myös viitteen luokka (staattinen luokka) voidaan tarvittaessa muuttaa toiseksi tyyppimuunnosoperaatiolla. Yleisesti: (LuokanNimi)viite ja ((LuokanNimi)viite).piirre missä LuokanNimi voi olla viitteen luokan esi-isän tai jälkeläisen nimi. // Luodaan Kissa-luokan olio ja asetetaan siihen Object-viite. Object mussu = new Kissa(); // Ei käänny. Staattinen luokka on Object, joka ei kehrää. mussu.kehraa(); // Kääntyy. Staattinen luokka tässä lauseessa Kissa. ((Kissa)mussu).kehraa(); 12.15

Tyyppimuunnos Alkuperäinen luokka palautuu muunnoksen jälkeen, mutta tarvittaessa muunnoksen tulos voidaan sijoittaa toiseen viitteeseen, jonka luokka on sama kuin muunnoksessa käytetty luokka. // Asetetaan olioon viite, jonka luokka on Kissa. Kissa mussu2 = (Kissa)mussu; // Onnistuu. Staattinen luokka Kissa. mussu2.kehraa(); Yleensä luokkatyyppi muunnetaan siten, että viitteen tyyppi muunnetaan alityypikseen (downcasting), koska monimuotoisuutta hyödynnetään usein parametrinvälityksessä. 12.16

Tyyppimuunnos Tyyppimuunnos on vaarallinen operaatio, koska kääntäjä tarkistaa vain onko tyyppimuunnos kieliopillisesti oikein. Tyyppimuunnosten avulla viite voidaan liittää täysin väärän tyyppiseen olioon, jolloin staattisen luokan piirteiden käsittely aiheuttaa ohjelman pysäyttävän poikkeuksen. Esim. // Staattinen luokka Object, dynaaminen Kissa. Object k = new Kissa(); // Voidaan muuntaa, koska Object > String, // mutta ohjelma kaatuu (ClassCastException). ((String)k).length(); 12.17

Tyyppimuunnos Ajonaikaisia tyyppitarkistuksia voidaan tehdä instanceofoperaattorilla ennen tyyppimuunnosta. public void rokota(nisakas n) { if (n instanceof Kissa) { // Tyyppimuunnos turvallinen, kun tiedetään // dynaamiseksi luokaksi Kissa. ((Kissa)n).sahise(); } else if (n instanceof Ihminen) { // Täällä rokotetaan ihminen 12.18

Rajapinnat ja alityypitys Rajapinnat noudattavat alityypityssääntöjä. Rajapinnan toteuttava luokka ja sen jälkeläiset katsotaan rajapinnan kanssa yhteensopiviksi. Oletetaan, että Kissa-luokka toteuttaa Tervehtiva-rajapinnan. // Staattinen ja dynaaminen luokka Kissa. Kissa mussu = new Kissa(); // Staattinen luokka Tervehtiva, dynaaminen luokka Kissa. Tervehtiva terve = mussu; terve.moikkaa(); terve.syo(); // Kääntyy; kutsutaan rajapinnan metodia. // Ei käänny; metodi ei viitteen luokassa. 12.19