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



Samankaltaiset tiedostot
OHJ-1450 Olio-ohjelmoinnin jatkokurssi lisämateriaalia

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

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

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

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

Mitä on periytyminen?

Muutamia peruskäsitteitä

Ohjelmistojen mallintaminen luokkamallin lisäpiirteitä

Sisällys. 11. Rajapinnat. Johdanto. Johdanto

TIE Ohjelmistojen suunnittelu

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

Solidity älysopimus ohjelmointi. Sopimus suuntautunut ohjelmointi

815338A Ohjelmointikielten periaatteet

TIE Ohjelmistojen suunnittelu

Ohjelmistoarkkitehtuurit Syksy 2009 TTY Ohjelmistotekniikka 1

Rajapinta (interface)

15. Ohjelmoinnin tekniikkaa 15.1

9. Periytyminen Javassa 9.1

TIE Ohjelmistojen suunnittelu. Kopiointia ja sijoittelua

TIE Ohjelmistojen suunnittelu. Kopiointia ja sijoittelua

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

Ohjelmistojen mallintaminen Luokkakaaviot Harri Laine 1

TIE Ohjelmistojen suunnittelu

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

15. Ohjelmoinnin tekniikkaa 15.1

9. Periytyminen Javassa 9.1

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

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

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

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

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

Osoitin ja viittaus C++:ssa

Ohjelmistojen mallintaminen. Luento 11, 7.12.

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op

Rajapinnat ja olioiden välittäminen

Virtuaalifunktiot ja polymorfismi

3. Komponentit ja rajapinnat

C++11 lambdat: [](){} Matti Rintala

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

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

Concurrency - Rinnakkaisuus. Group: 9 Joni Laine Juho Vähätalo

Kertaus: yleistys-erikoistus ja perintä

Objective-C. Ryhmä 35: Ilpo Kärki Aleksi Pälä

Ohjelmistojen mallintaminen luokkamallin lisäpiirteitä

C# ja.net. Juha Järvensivu 2007

Ohjelmoinnin peruskurssien laaja oppimäärä

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

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

TIE Ohjelmistojen suunnittelu

Uudelleenkäytön jako kahteen

TIE Ohjelmistojen suunnittelu

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

TIE Ohjelmistojen suunnittelu

Interaktiivisten järjestelmien arkkitehtuuriratkaisu, jolla käyttöliittymä erotetaan sovelluslogiikasta.

HELIA 1 (14) Outi Virkki Käyttöliittymät ja ohjlmiston suunnittelu

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

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

Periytyminen. Luokat ja olio-ohjelmointi

Olio-ohjelmointi Johdanto olio-ohjelmointiin

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

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

Hakemistojen sisällöt säilötään linkitetyille listalle.

Common Lisp Object System

ohjelman arkkitehtuurista.

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä

Linkitetystä listasta perittyä omaa listaa käytetään muun muassa viestiin liittyvien vastausten säilömiseen.

Ohjelmistotekniikan menetelmät, luokkamallin laatiminen

Graafisen käyttöliittymän ohjelmointi Syksy 2013

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

Ohjelmoinnin peruskurssien laaja oppimäärä

Kehyksillä toteuttettujen tuotelinjojen rakenteellinen optimointi

Olio-ohjelmointi Johdanto suunnittelumalleihin. 1. Yleistä

S11-09 Control System for an. Autonomous Household Robot Platform

TIE Ohjelmistojen suunnittelu. Viimeinen luento: kertaus

812341A Olio-ohjelmointi, I Johdanto

TIE Ohjelmistojen suunnittelu

Ohjelmoinnin jatkokurssi, kurssikoe

Luokkakaavion laatiminen

Ohjelmistoarkkitehtuurit kevät

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

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

Ohjelmointi II. Erkki Pesonen Luennot ja harjoitukset. Itä-Suomen yliopisto Tietojenkäsittelytieteen laitos 2015

Abstraktit tietotyypit ja olio-ohjelmointi

Sokkelon sisältö säilötään linkitetyille listalle ja tekstitiedostoon. Työ tehdään itsenäisesti yhden hengen ryhmissä. Ideoita voi vaihtaa koodia ei.

Graafisen käyttöliittymän ohjelmointi

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

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

TIE Ohjelmistojen suunnittelu

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

Ohjelmistojen mallintaminen. Luento 7,

Tapahtumapohjainen ohjelmointi

TIE Ohjelmistojen suunnittelu

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

Apuja ohjelmointiin» Yleisiä virheitä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmointi 1 / syksy /20: IDE

Esimerkkiprojekti. Mallivastauksen löydät Wroxin www-sivuilta. Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit

Yksikkötestaus. import org.junit.test; public class LaskinTest public void testlaskimenluonti() { Laskin laskin = new Laskin(); } }

TIE Ohjelmistojen suunnittelu

Ohjelmistojen mallintaminen viikon 4 laskareiden mallivastauksia

Transkriptio:

TIE-20200 Ohjelmistojen suunnittelu Luento 8..9: moniperintä 1

Ajankohtaista Harjoitustyön suunnittelusessiot pidetty, työt jatkuvat, välivaiheen esittely seuraavana Viimeinen viikkoharjoituskerta, palataan takaisin ensimmäisen viikon juttuihin

Ohjelmassa tänään Muutama plugin-esimerkki Pientä kirjastokomponenttijatkoa Rajapintojen rajoitteita Moniperintää

Moniperintää Periytymisessä luodaan uusi luokka periyttämällä siihen jonkun toisen luokan ominaisuudet Moniperintä, otetaan ominaisuuksia useammalta luokalta Ideatasolla erittäin yksinkertainen, mutta tekniikkana kiistelty (vaarallinenkin) Siksi ei mukana kaikissa oliokielissä

Moniperinnän ideasta Tavallinen periytyminen aliluokan olio kelpaa aina kantaluokan olioksi(solid: Liskov s substitution principle) Moniperinnässä aliluokka kuuluu kaikkiin kantaluokkiinsa, kelpaa minkä tahansa kantaluokkansa edustajaksi Periaate: Aliluokan olio on aina kaikkien kantaluokkiensa olio

Moniperintä ja ohjelmointikielet Jätetty kokonaan pois osasta kieliä (esim. Smalltalk, tosin smalltalkin tyypistystapa sallii vastaavien useilla luokilla toimivien rakenteiden luomisen) Osassa mukana osittain rajapintojen kautta, Java & C# Voidaan toteuttaa rajapintoja, tarjota erillisiä käyttö- ja kommunikointirajapintoja (normaalin luokkahierarkian ohessa) Ei kuitenkaan toteutuksen periytymistä Jotkut kielet sallivat täysimuotoisen moniperinnän, jättävät ohjelmoijan vastuulle välttyä ongelmilta Toistuvat rakenteet, diamond problem, miten käsitellään, riippuu vähän kielestä

Moniperintäesimerkki C++:lla Luokkahierarkia ja toteutettava rajapinta Kaksi kantaluokkaa, molemmilla omat funktionsa ja jäsenmuuttujansa ominaisuudet ja syntaksi identtisiä normaalin perinnän kanssa. Kaikki näkyvyysalueet jne. toimivat kuten tavallisessa versiossa. Samaa kantaluokkaa ei voi periä suoraan kahdesti (class Kahdesti: public Kantaluokka, public Kantaluokka) Mahdollista välillisesti

Moniperinnän käyttökohteita Rajapintojen yhdistäminen, luokka toteuttaa useita rajapintoja, helppo ilmaista Javan/C#:n ja esim. ohjelmoinnin tekniikat/alkuoliokurssin viitoittama tapa Moniperinnän käyttö suhteellisen mutkatonta, yleensä ongelmatontakin Kahden tai useamman olemassa olevan luokan yhdistäminen Esim. oliokirjastot, sovelluskehykset Luokkien koostaminen valmiista ominaisuuskokoelmista (mixin, flavours, jäätelöbaari-analogia) Ominaisuuksia, myytävä, lainattava Perustuotteita, kirja, peli Yhdistelmät, kirjaston kirja, myytävä peli Laajentaminen/yhdistäminen: rajapinta, jolle useita toteutuksia, peritään valittu toteutus (protokollat, algoritmit, tiedonesitysmuodot)

Moniperinnän vaaroja Yksinkertaisimmillaan: helppo käyttää väärin, helppo rikkoa olioajattelua (tehdään muurahaiskarhuja, otetaan mukaan kasapäin ylimääräistä yhden/muutaman ominaisuuden takia): ruutu&otus-esimerkki Perintää ei voi käyttää siihen, että olio on välillä yhden kantaluokkansa edustaja välillä toisen (esim. opiskelijatyypit, työntekijät) Moniperintää ei voi käyttää ottamaan yksittäistä ominaisuutta, is-a-suhteen on säilyttävä Kirjastonkirja perittynä päiväyksestä ja kirjasta Tekee ohjelman luokkarakenteesta helposti vaikeaselkoisempaa Elinkaaren hallinta voi vaikeutua (Esim. alustuslukija-ikkuna ja alustustiedotrajapinta) Moniperintää kannattaa välttää, jos mahdollista Kuitenkin hyvä & asiallinen käyttökohde, jos aliluokka kuuluu pysyvästi useampaan kantaluokkaan toteuttaen näiden rajapinnat, rajapintojen perintää ja toteuttamista

Moniselitteisyys Saman niminen funktio mahdollista saada kahdelta eri kantaluokalta Esim. kirjastonteos ja Kirja, molemmilla tulostatiedot funktio, mitä kirjastonkirjalla on? tai korttipakan kortti ja graafinen komponentti, perinnällä tehdään käyttöliittymään korttikomponentti. Molemmissa draw-funktiot. C++ ongelma tulee esiin, vaikka parametrityypissä olisi eroa Ratkaisu: sovitaan, että kutsutaan aina ensimmäisenä perintälistalla olevaa funktiota. Onko ok? Moniselitteinen funktiokutsu (amibiguous call), käänösaikainen ilmoitus

Moniselitteisyys C++:n ratkaisu, yritys kutsua useammasta eri kantaluokasta periytynyttä funktiota Moniselitteinen funktiokutsu (amibiguous call), käänösaikainen ilmoitus Usein kantaluokan saman nimiset funktiot tekevät saman tyyppisiä asioita (kuten kirjastonkirjaesimerkissä, toisin kuin korttijutussa) Jos jäsenfunktio virtuaalinen kaikissa kantaluokissa, voidaan kutsua jokaisen toteutusta vuorollaan (+tarvittaessa lisätä omia juttuja) Mitä tapahtuu ei-virtuaalisten funktioiden kanssa? Yleensä moniselitteisyys ei ratkea näin helposti Jos toiminnot keskenään yhteen sopimattomia, moniperityn aliluokan saaminen käyttäytymään kaikkien kantaluokkien kannalta oikein usein mahdotonta

Moniselitteisyys Ratkaisutapoja: kutsutaan kaikkien kantaluokkien toteutusta (kerrotaan nimiavaruus kutsussa) Jos aliluokka ei halua tarjota uutta toteutusta aliluokassa, homma toimii jos jäsenfunktioita ei kutsuta aliluokan tasolla Jos olioita käsitellään aliluokan tasolla, käytetään kuitenkin kantaluokkatason väliaikaisia osoittimia, viitteitä Kerrotaan mitä toteutusta halutaan käyttää (esim. Kirja::), ei välttämättä oliomaisinta Luodaan uudet keskenään erinimiset funktiot, jotka toimivat läpikutsuina kantaluokkaan

Toistuva moniperiytyminen ( Diamond problem ) (Repeated multiple inheritance, toistuva moniperiytyminen, dreaded diamond of death) Teos, KirjastonTeos, Kirja, Kirjastonkirja Esimerkki: GUI, GUI_Object, Rectangle, Clickable, Button Mitä ongelmia tästä saattaa tulla? Mikä on kirjastonkirjan rakenne?

Timanttista moniperintää Vaihtoehto 1: erilliset kantaluokkaosat, otetaan teoksen tiedot kahteen kertaan, erotteleva moniperiytyminen (replicated multiple inheritance) Vaihtoehto 2: yhteinen kantaluokkaosa, otetaan teos vain kertaalleen, virtuaalinen moniperiytyminen (virtual multiple inheritance) tai yhdistävä moniperintä (shared multiple inheritance) Kaksi kantaluokkaosaa, mitä ongelmia voi ilmetä? (kantaluokan nimimuuttuja) Yhteinen kantaluokka kaikilla, mitäs tämän kanssa? (rakentaminen)

Timanttista moniperintää Erotteleva moniperintä: Sama muuttuja kahteen kertaan, kahdesta eri suunnasta muutos, samalla muuttujalla kaksi eri arvoa (käytetään toisesta perittyä muuttamaan, toisen palvelua tulostamaan tietoja muutos ei näy) Kantaluokkaosoitin mahdoton, ei voida tietää kumpaan olio-osaan halutaan osoittaa/viitata Virtuaaliversio: Sallitaan erillisellä avainsanalla kantaluokan jakaminen (täytyy tehdä kaikissa luokissa joista ollaan perimässä) class Kirja : public virtual Teos // Tai virtual public... Tämän jälkeen moniperinnässä kaikki samasta kantaluokasta perityt luokat jakavat saman kantaluokan Rakentaminen, yksi olio voidaan rakentaa vain kertaalleen Rakentajakutsu tehdään moniperityssä luokassa suoraan yhteiselle kantaluokkatasolle, tämän jälkeen kutsutaan normaalisti kantaluokkien rakentajia Kääntäjä jättää kutsumatta näissä jo kertaalleen kutsuttua rakentaa

C++:n rajapintaluokat & moniperintä Kielessä ei erillistä rajapinnan tai abstraktin kantaluokan käsitettä Miten koodari voi vaikuttaa asiaan? Rakentajat purkajat huomioitava (tällä kertaa automaatiosta on iloa) Kantaluokalle kutsutaan automaattisesti oletusrakentajaa, jos kutsua ei itse määrittele Luokille tuotetaan automaattisesti oletusrakentaja, jos rakentajia ei määritä Purkajan oltava virtuaalinen, sille pitää olla toteutus, tyhjä toteutus pelkälle rajapinnalle hyvä pistää otsikkotiedostoon (ei turhaa toteutustiedostoa, kun kyseessä rajapinnan C++-vastine) Rajapintaluokkien yhdistäminen Ei toimi jälkikäteen koosteena tai kategorisointina (ei voi luoda uutta kahden rajapinnan yhdistelmää jonka alle kaikki nämä rajapinnat toteuttavat luokat automaattisesti kuuluisivat) Täytyy periä aliluokat rajapintayhdistelmistä (luokkahierarkia näyttää rumemmalta, mutta semanttisesti oikea tapa)

Qt ja moniperintä Koitetaan tehdä tapahtumankäsittelijärajapinta Peritään Qobjectista, saadaan mukaan eventit ja slotit Tehdään oma ikkuna, jonka halutaan kuuntelevan tapahtumia Miten toteutus?

Qobjectista ja moniperintä Ei sallita moniperintää Qobjectista käyttäjä ei voi tehdä samaa edes qobjectista perityn abstraktin luokan avulla Moniperinnässä Qobjectin (tai siitä perityn luokan) oltava ensimmäisenä listassa class JokuLuokka: public QObject, public JokuMuuLuokka Virtuaalinen perintä ei ole sallittua Qobjecteista asiaan liittyvää lisäinfoa: (http://qt-project.org/doc/qt-5.0/qtdoc/moc.html) Samankaltaiset rajoitteet/tilanteet mahdollisia myös muita kirjastoja käytettäessä Moniperinnän kanssa kannattaa olla varovainen, tarjolla kryptisiä virheilmoituksia jos suunnitteluperiaatteita rikkoo (C++-kääntäjän päälle tarvitaan laajennoksia, jos rajoituksia jne. halutaan käyttää)

Yhteenveto Moniperinnän kanssa kannattaa olla tarkkana Ennen kuin innostuu puljaamaan moniselitteisyyden jne. kanssa, kannattaa miettiä ohjelman rakennetta vielä kerran Kirjastot ja rajapinnan muuttaminen, kannattaa välttää jos mahdollista Rajapinnan laajentaminen, uusien palveluiden tarjoaminen Toiminnallisuuden korjaaminen TIE-20200 Samuel Lahtinen 19