12. Monimuotoisuus 12.1

Samankaltaiset tiedostot
12. Monimuotoisuus 12.1

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

9. Periytyminen Javassa 9.1

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

9. Periytyminen Javassa 9.1

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

Mitä on periytyminen?

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

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. 11. Rajapinnat. Johdanto. Johdanto

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

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

15. Ohjelmoinnin tekniikkaa 15.1

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

7. Oliot ja viitteet 7.1

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

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

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

15. Ohjelmoinnin tekniikkaa 15.1

14. Poikkeukset 14.1

20. Javan omat luokat 20.1

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

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

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

Java-kielen perusteet

4. Olio-ohjelmoinista lyhyesti 4.1

7. Näytölle tulostaminen 7.1

Oliot viestivät metodeja kutsuen

Olio-ohjelmointi Javalla

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

14. Poikkeukset 14.1

Taulukot. Jukka Harju, Jukka Juslin

Java-kielen perusteet

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

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

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op)

17. Javan omat luokat 17.1

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

Mikä yhteyssuhde on?

2. Olio-ohjelmoinista lyhyesti 2.1

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

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

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

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

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

Virtuaalifunktiot ja polymorfismi

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

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

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

19. Olio-ohjelmointia Javalla 19.1

Rajapinta (interface)

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

1. Omat operaatiot 1.1

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

Olio-ohjelmointi Syntaksikokoelma

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

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

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

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

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

17. Javan omat luokat 17.1

Muusta kuin vesisioista

Sisällys. 15. Lohkot. Lohkot. Lohkot

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

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

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

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

Metodien tekeminen Javalla

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

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

Ohjelmointi 2 / 2010 Välikoe / 26.3

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

815338A Ohjelmointikielten periaatteet

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

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

Muuttujat ja kontrolli. Ville Sundberg

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

13. Loogiset operaatiot 13.1

Javan perusteita. Janne Käki

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

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

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes)

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

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

Java-kielen perusteet

Olio-ohjelmointi Virhetilanteiden käsittely

KOHDELUOKAN MÄÄRITTELY

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä

Tietorakenteet. JAVA-OHJELMOINTI Osa 5: Tietorakenteita. Sisällys. Merkkijonot (String) Luokka String. Metodeja (public)

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

ITKP102 Ohjelmointi 1 (6 op)

13. Loogiset operaatiot 13.1

Rutiinin muodostaminen. 2. Rutiinin muodostaminen. specification) Määrittely (specification( Määrittelyn osapuolet. Hyvän ohjelman tunnusmerkit

Luokka Murtoluku uudelleen. Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista.

1 Tehtävän kuvaus ja analysointi

Tenttikysymykset. + UML-kaavioiden mallintamistehtävät

Transkriptio:

12. Monimuotoisuus 12.1

Sisällys Johdanto. Periytymismekanismi määrittää alityypityksen. Viitteiden sijoitus ja vertailu. Staattinen ja dynaaminen luokka. Myöhäinen ja aikainen sidonta. 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, mutta 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. Nisakas nisse = new Kissa(); New-operaattori palauttaa Kissatyyppisen nimettömän viitteen. Nisse-viitteen sijoitus onnistuu, koska Kissa-tyyppi on yhteensopiva Nisakas-tyypin kanssa eli Kissa <: Nisakas. Object apu = new String( abc ); Mihin tahansa luokan olioon voidaan sijoittaa Object-tyyppinen viite, koska kaikki luokkatyypit ovat yhteensopivia Object-tyypin kanssa. 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 esimerkiksi // kehrätä, koska staattinen // luokka on Nisakas. // Kääntäjä tuottaa virheen. nisse.kehraa(); nisse elossa, paino syo(), onkoiso() vari, hanta aantele(string), kehraa() Object-kerros Nisakas-kerros Kissa-kerros 12.10

Myöhäinen ja aikainen sidonta Monimuotoisuuden seurauksena metodista voi olla saatavilla useita versioita (korvaus) ja viitteeseen liittyvän olion tyyppi selviää usein vasta ohjelman ajon aikana, jolloin metodikutsut täytyy liittää metodien määrittelyihin vasta ohjelman ajon aikana. Metodien myöhäinen sidonta tehdään automaattisesti Javan virtuaalikoneen toimesta. Myöhäinen sidonta hidastaa ohjelmaa hieman. 12.11

Myöhäinen ja aikainen sidonta Aikainen sidonta on tyypillistä proseduraalisissa ohjelmointikielissä, joissa operaatioiden kutsut voidaan liittää määrittelyihin jo käännösaikana monimuotoisuuden puuttuessa. Aikainen sidonta nopeuttaa ohjelmaa. Javan luokkametodit eivät ole tietyn olion, vaan luokkansa omaisuutta ja voidaan siksi sitoa aikaisessa vaiheessa. Ohjelman toimintaa ei ole tarpeen tehostaa tällä kurssilla käyttämällä ilmentymämetodeja, koska runsas static-määreiden käyttö tekee ohjelmasta vähemmän oliomaisen. 12.12

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 viitteisiin liittyviä 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.13

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 liittyy 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 Operaattorin runsas käyttö ei ole suotavaa, koska yleensä pyritään mahdollisimman erillisiin luokkiin. 12.14

Tyyppimuunnos Eksplisiittiset tyyppimuunnokset ()-operaattorilla ovat tuttuja jo alkeistyyppien yhteydestä. // 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.15

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.16

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.17

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. // Staattinen luokka Object, dynaaminen Kissa. Object katti = new Kissa(); // Voidaan muuntaa, koska Object > String, // mutta ohjelma kaatuu (ClassCastException). ((String)katti).length(); 12.18

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.19

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.20