Ohjelmoinnin peruskurssien laaja oppimäärä



Samankaltaiset tiedostot
Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Perintä (inheritance)

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

Olio-ohjelmointi Javalla

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

Ohjelmoinnin peruskurssien laaja oppimäärä

9. Periytyminen Javassa 9.1

Javan perusteita. Janne Käki

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

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä

9. Periytyminen Javassa 9.1

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

String-vertailusta ja Scannerin käytöstä (1/2) String-vertailusta ja Scannerin käytöstä (2/2) Luentoesimerkki 4.1

1. Olio-ohjelmointi 1.1

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

Ohjelmoinnin peruskurssien laaja oppimäärä

Mikä yhteyssuhde on?

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

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

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Periytyminen (inheritance)

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

Ohjelmointikielet ja -paradigmat 5op. Markus Norrena

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

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

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

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

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

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

1 Tehtävän kuvaus ja analysointi

2. Olio-ohjelmoinista lyhyesti 2.1

Java kahdessa tunnissa. Jyry Suvilehto

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

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

Osion kaksi kertaus. Jukka Juslin. Jukka Juslin

Rajapinta (interface)

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

Ohjelmoinnin jatkokurssi, kurssikoe

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

16. Javan omat luokat 16.1

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

Ohjelmoinnin perusteet Y Python

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op

Ohjelmointi 2 / 2010 Välikoe / 26.3

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

812347A Olio-ohjelmointi, X Reflektiivisyys

Luokan sisällä on lista

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

ITKP102 Ohjelmointi 1 (6 op)

Oliot viestivät metodeja kutsuen

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

15. Ohjelmoinnin tekniikkaa 15.1

1. Omat operaatiot 1.1

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

815338A Ohjelmointikielten periaatteet

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

Metodien tekeminen Javalla

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

360 asteen kuvan tekeminen

Olio-ohjelmointi: Luokkien toteuttaminen. Jukka Juslin

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo

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

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

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

12. Monimuotoisuus 12.1

4. Olio-ohjelmoinista lyhyesti 4.1

Sisältö Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko metodin parametrina. Taulukko ja HelloWorld-ohjelma. Ta

812336A C++ -kielen perusteet,

20. Javan omat luokat 20.1

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

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

Pakkauksen kokoaminen

ITKP102 Ohjelmointi 1 (6 op)

Luokat ja oliot. Ville Sundberg

Tapahtumapohjainen ohjelmointi

ITKP102 Ohjelmointi 1 (6 op)

7. Oliot ja viitteet 7.1

- Kommentoi koodisi. Koodin kommentointiin kuuluu kuvata metodien toiminta ja pääohjelmassa tapahtuvat tärkeimmät toiminnat. Esim.

Ohjelmoinnin peruskurssien laaja oppimäärä

15. Ohjelmoinnin tekniikkaa 15.1

Tehtävä 1. Tehtävä 2. Arvosteluperusteet Koherentti selitys Koherentti esimerkki

Sisällys. 11. Rajapinnat. Johdanto. Johdanto

Muusta kuin vesisioista

Sisällys. 18. Abstraktit tietotyypit. Johdanto. Johdanto

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

JReleaser Yksikkötestaus ja JUnit. Mikko Mäkelä

Ohjelmoinnin peruskurssien laaja oppimäärä

Metodien tekeminen Javalla

Windows Live SkyDrive - esittely

17. Javan omat luokat 17.1

OHJ-1151 Ohjelmointi IIe

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

Ohjelmoinnin peruskurssien laaja oppimäärä

Taulukot. Jukka Harju, Jukka Juslin

12. Monimuotoisuus 12.1

Rinnakkaisohjelmointi kurssi. Opintopiiri työskentelyn raportti

Mitä on periytyminen?

18. Abstraktit tietotyypit 18.1

Transkriptio:

Ohjelmoinnin peruskurssien laaja oppimäärä Luento 10: Perintä, oliot vs. moduulit Riku Saikkonen (merkityt ei-laajan kurssin kalvot: Otto Seppälä) 26. 1. 2011

Sisältö 1 Ohjelmointikielten moduulijärjestelmistä 2 Oliot ja tavanomainen perintä 3 Metodien korvaaminen periessä 4 Olioiden toteutuksesta

Moduulit isommat ohjelmat jaetaan yleensä moduuleihin (module) moduulissa on sisäisiä muuttujia ja funktioita eli oma nimiavaruus moduulissa on (pitäisi olla?) selkeä ulkoinen rajapinta: esim. funktiot, joita moduuli tarjoaa (export) muulle koodille tavoite: ulkoisen rajapinnan dokumentaatio riittää moduulin käyttämiseen, eli sen sisuksista ei tarvitse välittää (moduuli tarjoaa yksittäistä funktiota suuremman kokonaisuuden abstraktion) mistä moduulien rajat keksitään? usein moduuli tekee tietyn toiminnon tai joukon tiettyyn asiaan liittyviä toimintoja tai käsittelee tiettyä (moduulin sisäistä) tietorakennetta esimerkkejä: jonotietorakenne, tietyn tiedostomuodon käsittely, debug-loggaus, lautapelin tekoäly yleiskäyttöisiä moduuleja ryhmitellään usein kirjastoiksi (library) terminologia vaihtelee hieman eri ohjelmointikielissä

Eri ohjelmointikielten tuki moduuleille useimmat ohjelmointikielet tarjoavat moduuleihin liittyen: tavan määritellä moduulin rajat näkyvyysasetukset: mitkä proseduureista tms. näkyvät muualle tavan kertoa moduulien riippuvuuksista (esim. import) usein moduuli = kooditiedosto esim. C-kielessä on tiedoston sisäisiä muuttujia ja funktioita (päätasolla oleva static) yleensä ohjelmia ei käännetä kokonaan kerralla vaan yksi tällainen moduuli/tiedosto kerrallaan joissakin kielissä koodissa on erillinen osa, joka kertoo vain moduulin ulkoisen rajapinnan (ei toteutusta) esim. C:n header-tiedostot ja ML:n signaturet moduulia käyttävää koodia voi kääntää tämän avulla (ilman moduulin toteutuksen lähdekoodia)

Lisäominaisuuksia moduulituessa useimmat kielet tukevat moduulien ryhmittelyä tai sisäkkäisiä moduuleita C:ssä kaksi tasoa: kooditiedosto ja kirjasto Javassa ja Pythonissa hierarkkiset nimet (esim. java.util.stack) muutama muu lisäominaisuus eri kielistä: osittainen import (Java, Python) osien uudelleennimeäminen importissa (Python) parametroidut moduulit (ML, Ocaml) moduulien tekeminen toisten moduulien pohjalta (Java, ML, Ocaml) moduulit kielessä käsiteltävänä arvona (PLT Scheme/Racket)

Moduulit oliokielissä Javassa moduulijako on hieman toisenlainen luokka moduuli (mutta olioissa on muutakin) paketti moduuli tai kirjasto (kirjasto on yksi tai useampi paketti) usein oliokielissä näkyvyydet (public, private yms.) määritellään metodien yhteydessä toinen vaihtoehto: kaikki metodit ovat periaatteessa public, mutta erillään niistä kerrotaan, mitkä luokat ja mitkä niiden metodeista kuuluvat moduulin julkiseen rajapintaan näin esim. Common Lispin oliojärjestelmässä etuja: moduulin rajapinta selvemmin yhdessä paikassa; sopii paremmin kieleen, jossa päätasolla on muutakin kuin luokkia haitta: metodiin liittyvä metatieto on koodissa hajallaan (näkyvyys eri paikassa kuin tyyppi yms.)

Miten moduulit toteutetaan? koodin jako moduuleihin onnistuisi ilman ohjelmointikielen tukea noudattamalla tarkkaa nimeämiskäytäntöä esim. Schemessä ja Emacs Lispissä näin usein tehdäänkin tämä ei toki isoissa ohjelmissa ole kovin kätevää... näkyvyydet voidaan tarkistaa käännösaikana siis (tavallisessa) moduulijärjestelmässä moduulien ei tarvitse näkyä ajon aikana teoriassa moduulijärjestelmän voisi toteuttaa esikäsittelemällä koodin ennen kääntäjälle antamista (tarkistetaan näkyvyydet ja nimetään kaikki uudestaan) käytännössä kuitenkin näkyy mm. debuggauksen ja osittaisen kääntämisen vuoksi moduulien toteuttamiseksi pitää myös määritellä mm. mistä muita moduuleja haetaan

Sisältö 1 Ohjelmointikielten moduulijärjestelmistä 2 Oliot ja tavanomainen perintä 3 Metodien korvaaminen periessä 4 Olioiden toteutuksesta

Millainen abstraktio olio on? olio-ohjelmoinnissa ratkaistava ongelma jaetaan osiin luokkien ja yksittäisten olioiden avulla puhtaimmillaan olio on (yleensä) itsenäinen kokonaisuus jolla on omaa tilaa (kentät) joka reagoi viesteihin (= metodikutsuihin) muuttamalla tilaansa tai lähettämällä muille viestejä olio-ohjelmoinnin tavoite (?): olioita käyttävä ohjelma on (vain) joukko itsenäisiä olioita, jotka hoitavat kukin omaa tehtäväänsä ja tarvittaessa kommunikoivat keskenään viesteillä ohjelman suorituksen aikana olioiden joukko muuttaa tilaansa alkutilasta (syötteen määräämään) tavoitetilaan useimmissa kielissä oliot tehdään luokkien avulla

(ei-laajan kurssin kalvo) Perintä (inheritance) Perintä on menetelmä, jonka avulla jostakin olemassaolevasta luokasta voidaan johtaa uusi luokka, joka saa automaattisesti käyttöönsä perimänsä luokan ominaisuuksia. Perittävää luokkaa kutsutaan yliluokaksi (superclass) Uutta, yliluokan ominaisuudet perivää luokkaa kutsutaan aliluokaksi (subclass) Periminen ilmaistaan luokan nimen jälkeen tulevalla sanalla extends, jota seuraa perittävän luokan (yliluokan) nimi. public public class class User User { { public public void void setpassword setpassword ( ( String String pass pass ) ) { {...toteutus...toteutus public public class class Admin Admin extends extends User User { {...... toteutus toteutus 02:10

(ei-laajan kurssin kalvo) Perintä (inheritance) Esimerkissä Admin-luokka perii luokan User Nyt Admin luokalla on perinnän kautta toteutus metodille setpassword. Luokka perii yliluokalta myös sen toteuttamat metodit, rajapinnat, yliluokat sekä kentät. Käytännössä Admin-oliot ovat myös yliluokkiensa (User ja Object) tyyppisiä (IsA-suhde) public public class class User User { { public public void void setpassword setpassword ( ( String String pass pass ) ) { {...toteutus...toteutus public public class class Admin Admin extends extends User User { {...... toteutus toteutus 02:10

(ei-laajan kurssin kalvo) Esimerkki Kirjaston tietokanta sisältää nykyisin varsin monenlaisia lainattavia asioita Kirjoja Kasetteja CD:itä Videoita DVD-levyjä Nuotteja, mikrofilmejä, jne... Näillä on paljon yhteisiä ominaisuuksia Luokkia mallinnettaessa yhteiset ominaisuudet tulisi mahdollisuuksien mukaan kerätä yliluokkaan. 02:10

(ei-laajan kurssin kalvo) Esimerkki: ennen perintää Luokissa on yhteisiä tai melkein yhteisiä toteutusosia Koodia toistetaan turhaan Ohjelmaa muutettaessa samat korjaukset tehdään kaikkiin luokkiin public class CD { public String getisbn(){... public String[] getartists(){... public class Book { public String getisbn(){ public Time getplaytime() {...... public String[] getauthors(){... public class Magazine { public String getisbn(){ public int getpages()... {... public String[] geteditors(){... public String getissn(){... 02:10

(ei-laajan kurssin kalvo) Esimerkki: perinnän jälkeen Yhteiset piirteet luokassa LibraryItem Kaikilla aliluokilla metodit getisbn ja getauthors public class LibraryItem { public String getisbn(){... public String[] getauthors(){... public class CD extends LibraryItem { public Time getplaytime() {... public class Book extends LibraryItem { public int getpages() { public class Magazine extends LibraryItem { public String getissn(){... 02:10

(ei-laajan kurssin kalvo) Perintähierarkia Yhdellä luokalla voi olla monta aliluokkaa ja millä tahansa aliluokalla taas omia aliluokkia jne. Perintähierarkia on termi, jolla viitataan siihen kuinka luokat perinnän kautta muodostavat puumaisen rakenteen jonka huipulla on Javassa luokka Object. Object Person JComponent String jne... Admin User JScrollPane 02:10

(ei-laajan kurssin kalvo) Perintä ja näkyvyys Protected-määre Private-määre rajaa näkyvyyden vain ja ainoastaan saman luokan olioihin. Public-määre tarjoaa täyden näkyvyyden koko maailmalle Protected sijoittuu puoliväliin Näkyy samaan luokkaan Näkyy kaikkiin kyseisen luokan aliluokkiin Pakettinäkyvyys (package-private) Neljäs näkyvyysmääre, joka ilmaistaan jättämällä näkyvyysmääre kirjoittamatta näkyy samaan pakettiin, mutta ei välitä perintäsuhteista 02:10

Perinnän ongelmia 1/2 edellisestä kirjastoesimerkistä: entä jos aluksi olisi tiedossa vain LibraryItemin tiedot, ja vasta myöhemmin selviäisi että olio onkin CD? entä jos sama LibraryItem sisältäisi kirjan ja CD:n? em. ongelmat syntyvät siitä, että oliolla on vain yksi luokka eikä sitä voi luomisen jälkeen muuttaa vrt. että LibraryItemin tyyppi ja lisätiedot olisivat kenttiä toisenlainen ongelma: mitä toimintoja ja koodia esim. jokin CD-olio kaiken kaikkiaan sisältää? tai: mihin koodiin on mahdollista mennä, kun CD-luokan metodi kutsuu toista saman olion metodia? periaatteessa pitää käydä koko perintähierarkia läpi dokumentointi ja ohjelmointityökalut (esim. Eclipse) auttavat mm. tämänkaltaisista syistä perintää käytetään usein paljon vähemmän kuin voisi kuvitella luokkahierarkiaa aluksi suunnitellessa syntyy helposti paljon syvempi hierarkia kuin mitä lopulta käytetään

Perinnän ongelmia 2/2 entä jos yliluokan toimintaa joutuu muuttamaan olennaisesti? kaikki aliluokat pitää käydä läpi ja tarkistaa siis yliluokkien toimintoja suunnitellessa pitää olla varovainen, jos aliluokkia on paljon mitä metodeja saa muuttaa luokkaa periessä ja miten? (siis mikä on perimisen kannalta luokan sisäistä tietoa) monimutkaista määritellä, joten jätetään usein tekemättä usein käytännössä tulee paljon tyhmiä metodeja, jotka vain välittävät viestejä eteenpäin toiselle oliolle tai rajapinnalle toinen joukko tyhmiä metodeja ovat useimmat get- ja set-metodit sekä jotkin konstruktorit monissa oliokielissä (mm. Common Lisp, Scala) onkin tapa tehdä näitä automaattisesti osalle näistä ongelmista on vastine myös ei-olio-ohjelmoinnissa

(ei-laajan kurssin kalvo) Perinnän etuja Koodia tarvitsee kirjoittaa vähemmän Uudelleenkäyttö (Reuse) Koodin ylläpito selkiytyy Muutokset yliluokkaan päivittyvät myös aliluokkiin Mallinnusnäkökulma Polymorfismin edut Olioita voidaan tarvittaessa käsitellä luokasta riippumatta yliluokan tasolla. 02:10

Sisältö 1 Ohjelmointikielten moduulijärjestelmistä 2 Oliot ja tavanomainen perintä 3 Metodien korvaaminen periessä 4 Olioiden toteutuksesta

(ei-laajan kurssin kalvo) Perintä ja konstruktorit Konstruktorit eivät periydy Jos teit konstruktorin joka saa vaikkapa parametrin tyyppiä String, täytyy aliluokkaan tehdä samanlainen konstruktori mikäli sellaista tarvitsee. Yliluokkien konstruktorit suoritetaan aina Jokaisen aliluokan konstruktori kutsuu aina yliluokan konstruktoria ennen kuin suorittaa oman osuutensa Käytännössä tämä tapahtuu laittamalla konstruktorin alkuun kutsu super(parametrit); aliluokan konstruktorin alkuun. Toimii samalla tavoin kuin kutsu this(parametrit); Jos kutsua ei laita, kääntäjä toimii kuin konstruktorissa kutsuttaisiin aluski yliluokan parametritonta konstruktoria Parametriton konstruktori on implisiittisesti olemassa jos muita konstruktoreita ei ole määritelty Jos yliluokkaan on kirjoitettu jokin konstruktori, täytyy aliluokan 02:10 kostruktorin kutsua yhtä määritellyistä konstruktoreista

(ei-laajan kurssin kalvo) Korvaaminen (Overriding) Perinnässä aliluokan metodi voi halutessaan korvata yliluokan toteutuksen toteuttamalla metodin jolla on sama puumerkki. Metodia kutsuttaessa suoritetaan aina aliluokan versio Aliluokan versio metodista korvaa yliluokan version 02:10

Samannimiset metodit mikä on metodin puumerkki (signature)? riippuu ohjelmointikielestä staattisesti tyypitetyissä oliokielissä (mm. Java) usein metodin nimi ja tyyppi (argumenttien ja paluuarvon tyyppi) dynaamisesti tyypitetyissä usein vain metodin nimi Javassa voi olla monta samannimistä metodia erityyppiset ovat eri metodeita (overloaded) aliluokan metodi korvaa (override) vain samantyyppisen metodin samannimisistä kutsuttava metodi valitaan argumenttien staattisen (käännösaikaisen) tyypin perusteella Esimerkkikoodi (Javaa) class A { void foo(integer x) {... void foo(string x) {... public static void main(string[] args) { A a = new A(); a.foo(new Integer(1)); a.foo("5");

(ei-laajan kurssin kalvo) Korvaaminen (Overriding) Lisätään kirjastoesimerkkiin metodi getdetails() Metodi palauttaa merkkijonoesityksen kulloisestakin esineestä. Metodin voi korvata aliluokassa, jolloin eri esineet voivat tulostaa erilaisen kuvauksen tyypistään riippuen Ongelma Nyt jokaisen aliluokan täytyisi toteuttaa ISBN-kenttien tms. tulostukset toisistaan erillään. Turhaa toistoa Voidaanko yliluokan getdetails-metodia käyttää apuna? 02:10

(ei-laajan kurssin kalvo) Korvaaminen (Overriding) Aliluokasta (ja vain sieltä) voidaan eksplisiittisesti kutsua yliluokan metodia super.metodi( parametrit ); Toisin kuin konstruktoreissa, tämän kutsun saa tehdä missä tahansa metodissa ja missä tahansa kohdassa. Yleensä kutsu tehdään vastaavassa aliluokan metodissa public abstract class LibraryItem { public String getdetails() { return Title: \t + title + \n + Authors:... etc... public class Magazine extends LibraryItem { public String getdetails() { return super.getdetails() + \n + ISSN: \t + issn + \n +... etc... public abstract class AudioItem extends LibraryItem { public String getdetails() { return super.getdetails() + \n + playtime: \t + reclength + \n +... etc... 02:10

Miten pitäisi periä? olio-ohjelmoinnissa aliluokan olio on (is a) myös yliluokan jäsen luokkaa periessä pitäisi aina säilyttää yliluokan toiminnot siis mihin tahansa koodiin, jossa käytetään yliluokan oliota, voisi sijoittaa aliluokan olion, niin että koodi edelleen toimii järkevästi toisin sanottuna: jokaisen yliluokan metodin (myös niiden, joita ei periessä korvaa!) semantiikka eli merkitys pitää säilyttää tämä nk. substituutioperiaate (Liskov Substitution Principle, LSP) on eräs perinnän käyttämisen perusohjeista käytännössä tästä kuitenkin aina välilllä poiketaan varsinkin yksityiskohdissa ja samalla oletetaan, ettei yliluokkaa käytetä väärin... usein ei ole tarpeeksi tarkkaan mietitty, mitä metodin pitäisi tehdä

Substituutioperiaatteen seurauksia Substituutioperiaate formaalisti ((sub)type (ali)luokka) Let φ(x) be a property provable about objects x of type T. Then φ(y) should be true for objects y of type S where S is a subtype of T. B. Liskov, J. Wing: A behavioral notion of subtyping. ACM Trans. on Prog. Lang. and Syst., 16(6), 1994. metodien tyyppeihin liittyen substituutioperiaatteesta seuraa: metodin argumentin tyyppiä voi aliluokassa yleistää muttei tiukentaa (argumenttityyppi on kontravariantti) metodin paluutyyppiä voi aliluokassa tiukentaa muttei yleistää (paluutyyppi on kovariantti) esim. Java ei kuitenkaan salli argumenttityypin muuttamista metodien ja koko olion toimintaan liittyen siitä seuraa mm: esiehtoja ei saa tiukentaa aliluokassa jälkiehtoja ei saa heikentää aliluokassa aliluokan olio ei saa muuttua yliluokan metodeista näkyvällä tavalla, joka ei olisi mahdollinen yliluokassa

Miksi perintä on tärkeää? miksi olio-ohjelmoinnissa puhutaan niin paljon juuri perinnästä? vaikka olio-ohjelmoinnissa on paljon muutakin, perinnän tuki erottaa olio-ohjelmointikielet muista kielistä usein monimutkaisemmat olio-ohjelmoinnin rakenteet (esim. suunnittelumallit) tarvitsevat perintää ilmankin perintää voi tehdä paljon olio-ohjelmointia esim. SICPin olioesimerkit (mm. jono, rajoitteiden vyörytys) moduuli joka käsittelee tiettyä tietorakennetta olio joten olioihin pohjautuvaa suunnittelua voi tehdä myös muissa kuin oliokielissä oliosuunnittelun perusidea: mallinnetaan ratkaistava ongelma itsenäisinä olioina, jotka kommunikoivat viesteillä; toteutuksen ei tarvitse olla oikea olio näin vältetään perinnän aiheuttamia ongelmia (mutta menetetään osa abstraktiomahdollisuuksista) jotkut eivät kuitenkaan pidä tätä varsinaisena olio-ohjelmointina

Sisältö 1 Ohjelmointikielten moduulijärjestelmistä 2 Oliot ja tavanomainen perintä 3 Metodien korvaaminen periessä 4 Olioiden toteutuksesta

Mitä metodikutsu tekee? Esimerkkikoodi (Javaa) class A { int foo(int x) { return x + 1; class B extends A { int foo(int x) { return x + 2; class Main { int printfoo(a obj) { A a = obj; System.out.println(a.foo(5)); public static void main(string[] args) { B obj = new B(); printfoo(obj); kumpaa foo()-metodia tässä kutsutaan?

(ei-laajan kurssin kalvo) Polymorfismi Polymorfismi Aliluokan olioihin voi viitata yliluokan tyyppisen muuttujan kautta. Kun tämän muuttujan kautta kutsutaan metodeja, suoritetaan silti aina toteutus joka sijaitsee aliluokista alimmassa. (korvaaminen) Tämän avulla eri oliot voidaan saada toimimaan eri tavoin niiden luokasta riippuen kun käsitellään joukkoa olioita yliluokan metodeja kutsuen. For-silmukassa jokainen kappale tallennettiin vuorollaan muuttujaan item. GetDetails-metodin kutsu suorittaa muuttujan osoittaman olion todellisen luokan version metodista getdetails. ArrayList<LibraryItem> allitems = new ArrayList<LibraryItem>(); allitems.add( new CD(...)); allitems.add( new Book(...)); allitems.add( new Magazine(...)); for (LibraryItem item : allitems) { System.out.println(item.getDetails()); allitems.get(2).destroyproperly(); 02:10

Dynaaminen vs. staattinen metodikutsu kutsuttava metodi valitaan siis dynaamisesti eli ajon aikana (dynamic dispatch, dynamic method lookup) eli ajon aikana joudutaan tekemään hiukan ylimääräistä työtä proseduurikutsuun verrattuna (nykyään merkityksetöntä) pohjimmiltaan juuri tämä ominaisuus määrittelee, mikä on olio-ohjelmointikieli tarkemmin: kieli tukee olio-ohjelmointia, jos se tarjoaa mahdollisuuden tehdä dynaamista metodinvalintaa toinen vaihtoehto olisi valita metodi olion käännösaikaisen tyypin mukaan eli staattisesti monet moduulijärjestelmät toimivat periaatteessa näin (esim. ML) koska metodi on tiedossa käännösaikana, tämän voisi toteuttaa esikäsittelemällä koodia (automaattisesti tai käsin) mm. C++-kielessä on molemmat vaihtoehdot

Javan static-metodit Java-metodin voi määritellä staticiksi, jolloin sitä voi kutsua pelkällä luokan nimellä static-metodi ei voi käyttää thisiä (sillä luokan oliota ei välttämättä edes ole) oikeastaan static-metodit eivät ole olio-ohjelmointia vaan osa Javan moduulijärjestelmää sillä metodinvalinta ei ole dynaamista ne siis käyttäytyvät kuin (hierarkkisesti nimetyt) globaalit funktiot toinen tapa ajatella: static-metodi on luokan metodi, ja kutakin luokkaa on ajon aikana olemassa vain yksi samoin static-kentät

Mitä oliosta on tallessa muistissa? ajon aikana luokat ja metodit ovat tiedossa (käännösaikana luotuja vakioita) sen sijaan kenttien arvot ovat jokaiselle oliolle yksilöllisiä ajon aikana jokaisesta oliosta on tallessa: kenttien arvot viittaus luokkaa ja metodeita kuvaaviin vakioihin mikä sitten on metodi? proseduuri, joka saa ylimääräisenä implisiittisenä argumenttina olion, jonka kautta metodia kutsuttiin (tästä tulee this) Python-kielessä tämä argumentti näkyy koodissa eksplisiittisesti metodista on siis muistissa vain koodi vrt. proseduuri Scheme-tulkissa: koodi ja määrittely-ympäristö (sisäkkäisten metodien tukemiseen tarvitsisi myös määrittely-ympäristöä)