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

Samankaltaiset tiedostot
12. Monimuotoisuus 12.1

815338A Ohjelmointikielten periaatteet

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

Olio-ohjelmointi Periytyminen ja monimuotoisuus. 1. Periytyminen

12. Monimuotoisuus 12.1

9. Periytyminen Javassa 9.1

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

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

9. Periytyminen Javassa 9.1

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

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

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

Rajapinta (interface)

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

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

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

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

Olio-ohjelmointi Javalla

Olio-ohjelmointi Syntaksikokoelma

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

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

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Java kahdessa tunnissa. Jyry Suvilehto

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

TIE Ohjelmistojen suunnittelu. Luento 8..9: moniperintä

812341A Olio-ohjelmointi, IX Olioiden välisistä yhteyksistä

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

1. Omat operaatiot 1.1

Abstraktit tietotyypit ja olio-ohjelmointi

Virtuaalifunktiot ja polymorfismi

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

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

Ohjelmistojen mallintaminen luokkamallin lisäpiirteitä

Ohjelmistojen mallintaminen Luokkakaaviot Harri Laine 1

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Pakkaukset ja määreet

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. II Johdanto olio-ohjelmointiin

Ohjelmointikieli TIE Principles of Programming Languages Syksy 2017 Ryhmä 19

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

15. Ohjelmoinnin tekniikkaa 15.1

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op

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

Aalto Yliopisto T Informaatioverkostot: Studio 1. Oliot ja luokat Javaohjelmoinnissa

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

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

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

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. VII Suunnittelumallit Adapter ja Composite

16. Javan omat luokat 16.1

Periytyminen (inheritance)

ITKP102 Ohjelmointi 1 (6 op)

Ohjelmoinnin peruskurssien laaja oppimäärä

Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat:

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

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. X Poikkeusten käsittelystä

ITKP102 Ohjelmointi 1 (6 op)

Javan perusteita. Janne Käki

C++ rautaisannos. Kolme tapaa sanoa, että tulostukseen käytetään standardikirjaston iostreamosassa määriteltyä, nimiavaruuden std oliota cout:

Muusta kuin vesisioista

Ohjelmoinnin jatkokurssi, kurssikoe

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

812336A C++ -kielen perusteet,

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

Taulukot. Jukka Harju, Jukka Juslin

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

C++11 Syntaksi. Jari-Pekka Voutilainen Jari-Pekka Voutilainen: C++11 Syntaksi

Metodien tekeminen Javalla

Ohjelmoinnin peruskurssien laaja oppimäärä

Osoitin ja viittaus C++:ssa

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

Ohjelmoinnin peruskurssien laaja oppimäärä

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

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

Ohjelmointikielet ja -paradigmat 5op. Markus Norrena

2. Olio-ohjelmoinista lyhyesti 2.1

Ohjelmoinnin peruskurssien laaja oppimäärä, kevät

Tehtävä 1. TL5302 Olio-ohjelmointi Koe Malliratkaisuja. Tässä sekä a)- että b)-kohdan toimiva ratkaisu:

ITKP102 Ohjelmointi 1 (6 op)

T Olio-ohjelmointi Osa 3: Luokka, muodostin ja hajotin, this-osoitin Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

Java-kielen perusteet

Luokan muodostimet (Constructors)

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

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. IX Suunnittelumallit Proxy, Factory Method, Prototype ja Singleton

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä

Mitä on periytyminen?

Common Lisp Object System

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

Vertailulauseet. Ehtolausekkeet. Vertailulauseet. Vertailulauseet. if-lauseke. if-lauseke. Javan perusteet 2004

D-OHJELMOINTIKIELI. AA-kerho, 33. Antti Uusimäki. Arto Savolainen

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

Tenttikysymykset. + UML-kaavioiden mallintamistehtävät

4. Olio-ohjelmoinista lyhyesti 4.1

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

Ohjelmistojen mallintaminen luokkamallin lisäpiirteitä

19. Olio-ohjelmointia Javalla 19.1

18. Abstraktit tietotyypit 18.1

TIE Samuel Lahtinen. Lyhyt UML-opas. UML -pikaesittely

\+jokin merkki tarkoittaa erikoismerkkiä; \n = uusi rivi.

Ohjelmoinnin peruskurssien laaja oppimäärä

Transkriptio:

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

Sisältö 1. Periytyminen 2. Johdanto monimuotoisuuteen 3. Ylikuormittaminen 4. Uudelleenmäärittely 5. Muuttujien monimuotoisuus 6. Multimetodit ja double dispatch monimuotoisuus 2

IV.1 Periytyminen Uudelleenkäytetään olemassaolevan luokan ominaisuuksia määriteltäessä uutta luokkaa Periytyvää luokkaa kutsutaan kantaluokaksi, perivää luokkaa aliluokaksi Periytymissuhteista muodostuu luokkahierarkia C++ tukee moniperiytymistä Perivä luokka perii useamman kantaluokan C++:ssa kolmen tyyppistä periytymistä Julkinen periytyminen Suojattu periytyminen Yksityinen periytyminen monimuotoisuus 3

IV.1.1 Julkinen periytyminen Tulee käyttää, kun perivää tyyppiä voidaan käyttää aina samassa yhteydessä kuin kantaluokkaa IS-A, WORKS-LIKE-A - periytyminen Tyyppiperiytyminen Perii sekä liittymän että toteutustavan Periytyminen näkyy luokkahierarkiasta ulospäin Yleisin periytymisen muoto Javassa ainoa monimuotoisuus 4

IV.1.1.1 Julkinen periytyminen ja näkyvyys Kantaluokan yksityiset (private) jäsenet eivät näy aliluokassa Periytyvät kuitenkin Ei voi siis käyttää suoraan Kantaluokan suojatut (protected) ja julkiset (public) jäsenet näkyvät aliluokassa Voidaan siis käyttää suoraan Jäsenten näkyvyys myös säilyy samana periytymisessä monimuotoisuus 5

Esimerkki julkisesta periytymisestä class A { public: void f(int); }; class B: public A // B perii luokan A { public: void f(double); }; monimuotoisuus 6

Esimerkki julkisesta periytymisestä (2) A a; B b; double x = 1.0; a.f(x); b.f(x); // Kutsuu A::f(int) // Kutsuu B::f(double) monimuotoisuus 7

Periytyminen graafisesti ColoredPoint Point -double x_coord -double y_coord -int color ColoredPoint perii Point-luokan ColoredPoint-olio sisältää Pointluokan olion monimuotoisuus 8

IV.1.1.2 Periytyminen ja muodostimet Kantaluokan jotakin muodostinta kutsutaan aina ensimmäiseksi kun aliluokan muodostinta kutsutaan Olio rakennetaan kantaluokasta aliluokkaa kohti Ellei aliluokan muodostimessa eksplisiittisesti kutsuta kantaluokan muodostinta, niin kutsutaan automaattisesti kantaluokan oletusmuodostinta Jos luokalla ei ole julkisia tai suojattuja muodostimia niin sitä ei voida käyttää kantaluokkana monimuotoisuus 9

IV.1.1.2 Periytyminen ja hajotin Kun aliluokan olio tuhotaan, aliluokan hajotinta kutsutaan ensin ja sitten kantaluokan hajotinta Olio tuhotaan aliluokasta kantaluokkaa kohti monimuotoisuus 10

Esimerkki muodostimista class Kanta{ public: Kanta() {...} protected: Kanta(int i) {...} private: }; class Ali : public Kanta{ public: Ali(); Ali(int i); ); monimuotoisuus 11

Esimerkki muodostimista (2) Ali::Ali() // implisiittinen Kanta() -kutsu { } Ali::Ali(int i) : Kanta(i) // eksplisiittinen Kanta(int) -kutsu { } monimuotoisuus 12

IV.1.2 Toteutustavan periytyminen Joko yksityinen tai suojattu periytyminen Yksityinen periytyminen Kantaluokan (kantaluokkien) kaikki jäsenet ovat yksityisiä alaluokassa. public -> private protected -> private Kantaluokan yksityiset jäsenet eivät ole käytettävissä Suojattu periytyminen Kantaluokan (kantaluokkien) kaikki jäsenet ovat yksityisiä alaluokassa. public -> protected protected -> private Kantaluokan yksityiset jäsenet eivät ole käytettävissä monimuotoisuus 13

IV.1.3. Moniperiytyminen Moniperiytymisessä luokka perii useamman kantaluokan täsmälleen samoin kuin yksinkertaisessa perinnässä -> aliluokalla on useampi kantaluokka Johdettu luokka sisältää kantaluokan aliolion jokaisesta sen kantaluokasta Ensimmäisiä lisäominaisuuksia C++:aan C++:ssa olioilla ei yhteistä kantaluokkaa -> moniperintä katsottiin välttämättömäksi säiliöiden toteuttamiseksi monimuotoisuus 14

IV.1.3. Moniperiytyminen (2) Kantaluokkien muodostimia kutsutaan siinä järjestyksessä kuin ne on määritelty kantaluokiksi Hajottimien kutsujärjestys on päinvastainen A B C A B C A B Muodostin C C B A Hajotin monimuotoisuus 15

IV.1.3. Moniperiytyminen: Esimerkki class ZooAnimal{ public: virtual ~ZooAnimal() {} }; class Bear : public ZooAnimal{}; class Endangered {}; class Panda: public Bear, public Endangered{}; int main() { Panda p; // Muodostimien kutsut: // ZooAnimal, Bear, Endangered, Panda } // Hajottimien kutsut: // ~Panda, ~Endangered, ~Bear, ~ZooAnimal monimuotoisuus 16

IV.1.3.1 Erotteleva ja yhdistävä moniperiytyminen Oletusarvoisesti C++:ssa moniperiytyminen erottelevaa: class Kanta { // JNE class EkaSolmu: public Kanta { // JNE class TokaSolmu: public Kanta { // JNE class Ali: public EkaSolmu, public TokaSolmu { //JNE Ali-luokka sisältää kaksi ilmentymää Kanta-luokan tiedoista monimuotoisuus 17

IV.1.3.1 Erotteleva ja yhdistävä moniperiytyminen (2) Voidaan käyttää myös virtuaalista eli yhdistävää moniperiytymistä: class Kanta { // JNE class EkaSolmu: public virtual Kanta { // JNE class TokaSolmu: public virtual Kanta { // JNE class Ali: public EkaSolmu, public TokaSolmu { //JNE Nyt Ali-luokassa vain yksi ilmentymä Kanta-luokan tiedoista monimuotoisuus 18

IV.1.3.2 Virtuaalinen moniperiytyminen graafisesti B C A A A B C D Tavallinen, erotteleva moniperiytyminen D Virtuaalinen, yhdistävä moniperiytyminen monimuotoisuus 19

IV.1.3.3 Vertailua Javaan Javassa ei moniperiytymistä Javassa luokkien lisäksi rajapintoja (interface) Rajapinnat sisältävät vain metodien esittelyjä, ei toiminnallisuutta Javan luokka voi periä yhden luokan mutta toteuttaa (implements) sen lisäksi useita rajapintoja Luokkaan toteutetaan rajapinnan esittelemät metodit C++:ssa ei rajapinnan käsitettä Voidaan toteuttaa tekemällä luokka, jossa vain puhtaasti virtuaalisia metodeja monimuotoisuus 20

IV.2. Johdanto monimuotoisuuteen Olio-ohjelmoinnin kolme tukipilaria: 1. Tiedon kapselointi ja kätkentä 2. Periytyminen 3. Monimuotoisuus Monimuotoisuus (polymorfismi): Olion kyky reagoida samaan viestiin eri lailla tilanteesta riippuen Termillä ei yhtä yksikäsitteistä määritelmää Ehkä tyypillisin olio-ohjelmointiparadigman ominaisuus monimuotoisuus 21

IV.2.1 Monimuotoisuuden ilmenemismuodot 1. Operaation ylikuormittaminen Tavallisimmin: Useampia samannimisiä funktioita samassa moduulissa 2. Operaation uudelleenmäärittely Sama metodi yli- ja aliluokissa 3. Muuttujien monimuotoisuus Sama muuttuja voi viitata eri tyyppisiin olioihin 4. Geneerisyys Tyyppiriippumattomuus, tyypit parametreina Käsitellään myöhemmin monimuotoisuus 22

IV.3. Ylikuormittaminen (Overloading) Metodin (funktion) nimi on monimuotoinen, ts. samannimisellä metodilla useita toteutuksia Poikkeavat parametrilistaltaan tai Ovat eri näkymäalueessa Kääntäjä päättelee kutsun parametrien perusteella, mihin toteutuksen sidotaan Staattinen monimuotoisuuden muoto Toteuttamiseen ei tarvita oliokieltä monimuotoisuus 23

IV.3.1 Ylikuormittaminen näkymäalueen suhteen Luokka muodostaa näkymäalueen -> eri luokissa voi olla samannimisiä ja samantyyppisiä metodeja Ei edellytetä semanttista yhteyttä metodien välillä class DialogWindow { public: void draw() {} }; class Artist { public: void draw(){} }; Näkymäalueen suhteen ylikuormitetut metodit Tästä eteenpäin käsitellään ylikuormittamista parametrien suhteen! monimuotoisuus 24

IV.3.2 Konstruktorin ylikuormittaminen Erittäin yleistä, esim. Javan String-luokan konstruktoreita: String()... an empty character sequence. String(char[] value)... represents the sequence of characters currently contained in the character array argument. String(String original)...initializes a newly created String object so that it represents the same sequence of characters as the argument. -> Voidaan luoda String-olioita mm. seuraavasti: String s = new String(); // s = char merkit[] = { h, e, i }; String t = new String(merkit); // t = hei String u = new String(t); // u = hei monimuotoisuus 25

IV.3.3 Operaattoreiden ylikuormittaminen Kielen operaattoreiden laajentaminen omille tyypeille Parantaa ohjelman luettavuutta, mikäli operaattorin semantiikkaa ei muuteta Esimerkki: Kirjoitettu luokka Piste, joka mallintaa tason pisteitä. Halutaan käyttää operaattoria + pisteiden yhteenlaskuun: Piste p(2,3); Piste q(4,5); Piste r = p+q; // r = (6,8); Onnistuuko? Javassa ei sallittu monimuotoisuus 26

IV.3.3 Operaattoreiden ylikuormittaminen (2) C++:ssa operaattorit funktioita tai luokkien metodeja, jotka voidaan ylikuormittaa Lähes kaikki operaattorit ylikuormitettavia Operaattoreiden ylikuormittamisella ei pystytä muuttamaan Operaattoreiden sidontajärjestystä Tulkintasuuntaa Uusia operaattoreita ei voi tehdä monimuotoisuus 27

IV.3.3.1 Esimerkki, operaattorit + ja += class Piste{ public: Piste& operator+=(const Piste &p); //... }; Piste operator+(const Piste& p1, const Piste& p2); Piste& Piste::operator+=(const Piste &p){ x_coord = x_coord+p.x_coord; y_coord = y_coord+p.y_coord; return *this; } Piste operator+(const Piste& p1, const Piste& p2){ Piste p(p1); p += p2; return p; } Tiedosto Piste.h Tiedosto Piste.cpp monimuotoisuus 28

IV.4 Uudelleenmäärittely (Overriding): Aluksi Staattinen sidonta = aikainen sidonta Metodin kutsu liitetään käännöksen aikana tiettyyn aliohjelmaan Dynaaminen sidonta = myöhäinen sidonta Kutsuttava metodi päätellään vasta ohjelman suorituksen aikana Alityyppiperiaate ( Liskov substitution principle ): Aliluokan olio voi esiintyä kaikissa yhteyksissä, joissa yliluokan olio esiintyy C++:ssa ei yleisesti voimassa Javassa aina voimassa monimuotoisuus 29

IV.4 Uudelleenmäärittely Aliluokan metodi saman niminen, sillä on sama parametrilista ja paluuarvo kuin yliluokan metodilla Yliluokan metodin toteutus peittyy Javassa näkyvyysmääre ei saa olla aliluokassa tiukempi, C++:ssa voi vaihtaa mielivaltaisesti Dynaaminen sidonta + alityyppiperiaate tekevät uudelleenmäärittelystä vahvan monimuotoisuuden työkalun monimuotoisuus 30

IV.4.1 Virtuaalioperaatiot Operaatio (metodi), johon voidaan soveltaa myöhäistä sidontaa, on virtuaalioperaatio Virtuaalioperaatio, jolle määritellään yliluokassa myös toteutus, on kiinnitetty virtuaalioperaatio Toteutus on oletus, voidaan syrjäyttää aliluokissa Avoin virtuaalioperaatio = abstrakti metodi Yliluokka ei määrittele toteutusta lainkaan Luokka, jolla on abstrakteja metodeja, on abstrakti luokka. Sellaisesta ei voida luoda olioita Jos luokka ei ole abstrakti, se on konkreettinen monimuotoisuus 31

IV.4.1 Virtuaalioperaatiot: Haittoja Metodien virtuaalisuus tekee ohjelmasta vaikeammin ymmärrettävän ja heikentää luokkahierarkian seurattavuutta Virtuaalioperaatioiden ajonaikainen sitominen myös hidastaa ohjelman suorittamista monimuotoisuus 32

IV.4.2 Virtuaalioperaatiot eri kielissä Smalltalk ja Eiffel: Kaikki operaatiot virtuaalisia Java: Operaatiot virtuaalisia, mutta ohjelmoija voi estää korvaamisen aliluokissa (final) C++ ja Simula: Ohjelmoija päättää, mitkä operaatiot virtuaalisia C++: oletus ei-virtuaalinen monimuotoisuus 33

IV.4.2.1 Esimerkki class Person{ private: string name; public: virtual void print() const; virtual void tmeth(){}; Person(string str):name(str){}; }; class Employee : public Person { private: string status; public: }; void print() const; Employee(string n, string s):person(n),status(s){}; Sidotaan dynaamisesti; virtual pois -> sidotaan staattisesti monimuotoisuus 34

IV.4.3 Dynaamisen sidonnan toteutuksesta Miten löydetään kutsuttaessa oikea metodi? Suoraviivaisin tapa: Tallennetaan jokaiseen olioon ylimääräinen tietokenttä, joka osoittaa oikeaan metodiin Haaskaa tilaa, ei yleensä käytetä Useimmissa käännettävissä oliokielissä käytetään virtuaalitauluja Virtuaalitaulun alkiot ovat osoittimia metodeihin Jos aliluokka ylimäärittelee virtuaalisen metodin, osoitin tähän metodiin. Muussa tapauksessa yliluokan metodiin Saman luokan instansseilla yhteinen taulu monimuotoisuus 35

IV.4.3 Dynaamisen sidonnan toteutuksesta (2) EE Person Attributes Methods Virtual methods print = &Person::print tmeth = &Person::tMeth Employee Attributes Methods Virtual methods print = &Employee::print tmeth = &Person::tMeth p1 p2 Person-luokan virtuaalitaulu Employee-luokan virtuaalitaulu Person* p1 = new Person(); Person* p2 = new Employee(); Person::print Person::tMeth Employee::print Person::tMeth monimuotoisuus 36

IV.4.4 Uudelleenmäärittelyn toteutuksesta Korvaaminen (replacement) Aliluokan metodi korvaa täysin yliluokan metodin Amerikkalainen semantiikka Tarkentaminen (refinement) Aliluokan metodissa suoritetaan ensin yliluokan metodi + muut määritellyt operaatiot Skandinaavinen semantiikka monimuotoisuus 37

III.4.4 Toteutuksesta: Java ja C++ Korvaaminen yleisempi tapa nykykielissä Tarkentamista käytetään konstruktoreissa Sekä Java että C++: Aliluokan oliota luotaessa kutsutaan aina jotakin yliluokan konstruktoria Java ja C++: Konstruktoreita lukuunottamatta käytetään korvaamista Tarkentaminen voidaan määritellä tehtäväksi aliluokan metodissa C++: Yliluokka::metodi() Java: super-viite monimuotoisuus 38

III.4.5 Kovarianssi (Covariant change) Uudelleenmääritellyn metodin paluuarvo tai parametrit muuttuvat samaan suuntaan luokkahierarkian kanssa Ovat siis tarkempia kuin yliluokassa Parametreissa kovarianssi ei yleensä onnistu class Kanta { }; public: virtual boolean equals(kanta& k){/*vrt.*/} class Kovar: public Kanta { }; public: boolean equals(kovar& k) { // EI KORVAA Kanta-luokan // metodia equals(kanta k) return true; } monimuotoisuus 39

IV.4.5 Kovarianssi (2) Paluuarvossa kovarianssi semanttisesti mahdollinen Myös Javan uudemmissa versioissa onnistuu class Yli { }; // Yli-luokan alityyppi class Ali: public Yli { }; class Kovar { public: virtual Yli* teeolio(){ return new Yli(); } }; class KovarAli: public Kovar { public: Ali* teeolio() { return new Ali(); } }; Paluuarvo muuttuu alaspäin luokkahierarkiassa Korvaa Kovar-luokan metodin teeolio() monimuotoisuus 40

IV.4.6 Kontravarianssi (Contravariant change) Uudelleenmääritellyn metodin paluuarvo tai parametrit muuttuvat päinvastaiseen suuntaan luokkahierarkian kanssa Ovat siis yleisempiä kuin yliluokassa Paluuarvossa hankala toteuttaa Ei C++:ssa eikä Javassakaan käy Parametreissa mahdollista ainakin kääntää Eiffel-kielessä tapahtuu korvaaminen C++:ssa ja Javassa ei tapahdu korvaamista monimuotoisuus 41

IV.4.6.1 Kontravarianssi paluuarvossa Alla oleva C++-koodi ei käänny! class Yli { }; // Yli-luokan alityyppi class Ali: public Yli { }; class Kontravar { public: virtual Ali* teeolio(){ return new Ali(); } }; class KontravarAli: public Kontravar { public: Yli *teeolio() { return new Yli(); } }; Paluuarvo muuttuu ylöspäin luokkahierarkiassa monimuotoisuus 42

IV.4.6.2 Kontravarianssi parametreissa C++:ssa voi käyttää syntaktisesti, ei aiheuta metodin uudelleenmäärittelyä class Yli { } // Yli-luokan alityyppi class Ali: public Yli { } class Kontravar { public: virtual void oper(ali &a) { } } class KontravarAli extends Kontravar { public void oper(yli &y) { } } Parametri muuttuu ylöspäin luokkahierarkiassa Ei korvaa Kontravarluokan metodia oper()! monimuotoisuus 43

IV.5 Muuttujien monimuotoisuus Muuttuja voi viitata monentyyppiseen olioon Dynaamisesti tyypitetyissä kielissä kaikki muuttujat monimuotoisia Monet skriptikielet Staattisesti tyypitetyissä kaikilla muuttujilla tyyppi, joka annetaan määrittelyn yhteydessä Esim. Java, C++ Muuttujan monimuotoisuus: Voi viitata myös tyyppinsä alityyppisiin olioihin Tyypillinen käyttötapa: monimuotoiset säiliöt monimuotoisuus 44

IV.5.1 Downcasting Tyyppimuunnos, joka tapahtuu alaspäin luokkahierarkiassa Muunnos ylöspäin yleensä aina sallittu Tarvitaan joskus, kun muuttuja yliluokan tyyppinen, mutta halutaan kutsua aliluokan operaatiota, jota ei yliluokassa ole Varmistettava, että muunnos laillinen! Yleensä kielessä mekanismi, jolla voidaan tarkistaa onko sallittu Java: instanceof-operaattori tarkistaa olion tyypin C++: dynamic_cast-operaattori tarkistaa onko muunnos laillinen monimuotoisuus 45

IV.6 Multi-metodit ja double dispatch Ongelma: Ylikuormitettujen metodien parametrit voivat olla alityyppejä ja ylikuormitetun metodin sitominen on käännösaikaista. Miten metodikutsu saadaan toimimaan tarkoitetulla tavalla, ts. kutsu tehtäisiin parametrien ajonaikaisten tyyppien perusteella? (Multi-metodi) Esim. class Yli{ }; class Ali: public Yli { }; Metodeja: void fun(yli& x, Yli& y) void fun(yli& x, Ali& y) void fun(ali& x, Yli& y) void fun(ali& x, Ali& y) Ohjelmassa: Yli* a =... Yli* b =... Voivat viitata sekä Yliettä Ali-luokan olioihin // Mitä metodia kutsutaan? fun(*a, *b); monimuotoisuus 46

IV.6.1 Multi-metodit ja double dispatch (2) Edellinen ongelma hankala staattisesti tyypitetyissä kielissä. Yksi ratkaisu: olio tietää itse oman tyyppinsä, viesti ohjataan sen mukaan Luokkiin kirjoitettava dynaamisesti sidottavat metodit, jotka korvaavat toiminnan class Yli{ void fun(yli& x){ x.funyli(*this);} void funyli(yli& x){ //fun(yli&,yli&);} void funali(yli& x){ // fun(ali&,yli&);} }; Pääohjelmassa: Yli *a = new Ali(); Yli *b = new Ali(); a->fun(*b); class Ali: public Yli { void fun(yli& x){ x.funali(*this);} void funyli(yli& x){ // fun(yli&,ali&)} void funali(yli& x){ // fun(ali&,ali&)} }; monimuotoisuus 47