Polymorfismi Sisältö Mitä on polymorfismi?

Slides:



Advertisements
Samankaltaiset esitykset
Tuloksellinen Java-ohjelmointi Luku 3 Luokkien käyttäminen
Advertisements

Rajapintaluokat Rajapintaluokka luettelee metodit, joille tulee löytyä toteutus asianomaisen rajapinnan toteuttavista luokista. Rajapintaluokka on siis.
Minimaalinen Java-ohjelma •Kaikki ohjelmakoodi on luokkamäärityksen sisällä •Ohjelma käynnistyy ”public static void main(String[] args)”-metodista •System.out.print()
Osion kaksi kertaus Jukka Juslin © Jukka Juslin.
6. Metodit.
@ Leena Lahtinen Helia TIETO JA TIETOKONEOHJELMA  TIETOKONEOHJELMA KÄSITTELEE TIETOJA  TIETOJA VOIDAAN KÄSITELLÄ OHJELMASSA VAIN SALLITUILLA.
© Jukka Harju, Viittausmuuttujat. © Jukka Harju, Viittaukset •Viittausmuuttuja sisältää tiedon siitä missä muistipaikassa olio.
© Jukka Harju, Jukka Juslin1 Java-ohjelmointi opas ammattimaiseen osaamiseen Luku 13 Monimuotoisuus.
© Jukka Harju, Jukka Juslin1 Java-ohjelmointi opas ammattimaiseen osaamiseen Luku 12 Periytyminen.
16. Javan omat luokat.
Ict1td002: Ohjelmointitaito Kertaus Osio 2 - luokat - ilmentymät - viittaus- ja arvomuuttuja - ilmentymien taulukointi HAAGA-HELIA IltaTiko.
Nämä kalvot on lisensoitu Creative Commons Attribution-ShareAlike 1
Tuloksellinen Java-ohjelmointi Luku 9 Taulukot ja perustietorakenteet
Jukka Juslin Poikkeukset ja niiden paikallistaminen * Jukka Juslin * Liittyy oppikirjan lukuun 11.
Taulukot Jukka Juslin © Jukka Juslin 2006.
Taulukoiden määrittely, käsittely ja kopiointi Vaihtoehdot taulukoille
Johdetun luokan määrittely tMyn1 Johdetun luokan määrittely •Kun johdettu luokka periytetään kantaluokasta, saadaan kantaluokan jäsenet enemmän tai vähemmän.
13. Pakkaukset.
Perintä. Yleistä Olio-ohjelmoinnin menetelmä muodostaa uusia luokkia aiemmin määriteltyjen luokkien avulla Luokka saa automaattisesti käyttöönsä kaikki.
OHJELMAN OSITTAMINEN LUOKKA ATTRIBUUTIT METODIT. LUOKKA JAVA ohjelma koostuu luokista LUOKKA sisältää metodeja molemmat sisältävät attribuutteja eli muuttujia.
@ Leena Lahtinen OHJELMAN OSITTAMINEN LUOKKA ATTRIBUUTIT METODIT.
© Jukka Harju, Jukka Juslin Java-ohjelmointi Opas ammattimaiseen osaamiseen Luku 9 Poikkeuskäsittely.
Poikkeustenkäsittely  Mitä poikkeustenkäsittely tarkoittaa?  Poikkeuksen käsitteleminen  Poikkeusluokkien hierarkia  Poikkeuksen heittäminen 1.
9. Periytyminen Javassa.
TIETO JA TIETOKONEOHJELMA TIETOKONEOHJELMA KÄSITTELEE TIETOJA TIETOJA VOIDAAN KÄSITELLÄ OHJELMASSA VAIN SALLITUILLA MENETELMILLÄ.
13. Hyvä ohjelmointitapa (osa 1)
© Jukka Harju, Jukka Juslin
1 Kertaus koetta varten oleellisista asioista Jukka Juslin.
Map-luokka Mikä Map on? Mapin esittely ja luonti Map-luokan metodeja Mappiin lisääminen Mapin läpikäynti Mapista poistaminen 1.
Lännen Tehtaat Osavuosikatsaus
Lännen Tehtaat Osavuosikatsaus
Metodit – Arvotyyppi Ellei metodi palauta arvoa, sen arvotyyppi on void Tällöin ”return;”-lauseke ei ole metodissa pakollinen, vaikka sen käyttö on sallittua.
20. Javan omat luokat.
1 DataOutputStream ja DataInputStream DataOutputStream:lla voidaan tallentaa perustietotyyppien arvoja binäärimuotoiseen tiedostoon DataInputStream:lla.
4. Attribuutit 4.1. Sisällys Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2.
5. Kapselointi Yleistä Kapseloinnilla (encapsulation) tarkoitetaan luokan tietojen ja toimintojen pakkaamista yhdeksi suojatuksi kokonaisuudeksi.
10. Abstrakti luokka Johdanto Abstrakti luokka (abstract class) poikkeaa konkreettisesta luokasta (ei-abstrakti luokka) siten, että siitä ei.
@ Leena Lahtinen OHJELMAN OSITTAMINEN LUOKKA ATTRIBUUTIT METODIT.
Hyvä ohjelmointitapa (osa 2) Yleistä Lisää hyviä ohjelmointikäytäntöjä: − Jaa pitkä koodi osiin. − Käytä attribuutteja säästeliäästi.
22. Taulukot.
17. Kooste Kooste Kooste (aggregation) on luokkien A ja B välinen suhde, joka tarkoittaa “A on B:n osa” tai “A kuuluu B:hen”. − Koostesuhteessa.
Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Pakkaukset ja määreet.
@ Leena Lahtinen TIETOKONEOHJELMAN RAKENNE OHJELMALLA ON KAKSI OSAA:  MÄÄRITYSOSA TIETOJEN KUVAUKSIA VARTEN  SUORITUSOSA TIETOJEN KÄSITTELYÄ.
Oliot ja luokat Oliot ja luokat Oliot (object) ja luokat (class) ovat keskeisiä olio- ohjelmoinnin käsitteitä. Olio-ohjelmointi on ohjelmointiparadigma,
© Jukka Harju, Sisältö 1. Mitä on periytyminen Javassa? 2. Periytyminen UML-luokkakaaviossa 3. Termejä 4. Periytymishierarkia 5. Periytyminen vs.
Vesa Ollikainen & Outi Grotenfelt
Olioiden taulukointi Perustaulukon käyttö Luokan ilmentymät voidaan tallettaa taulukkoon samoin kuin muuttujat Esimerkki talletetaan taulukkoon opintojaksojen.
11. Rajapinnat Sisällys Mitä rajapinnat ovat? Kuinka ne määritellään ja otetaan käyttöön? Moniperiytyminen rajapintojen avulla. Varoituksen.
Monimuotoinen luokka tMyn1 Monimuotoinen luokka Monimuotoinen luokka mahdollistaa saman jäsenfunktion toteutuksen monella tavalla. Tällöin puhutaan virtuaalisesta.
Johdetun luokan olion alustus tMyn1 Johdetun luokan olion alustus määrätyillä arvoilla Kun ohjelmassa esiintyy johdetun luokan olion määrittely, järjestelmä.
Kantaluokan määrittely tMyn1 Kantaluokan määrittely Perinnän käyttöön liittyvät varatut sanat private, protected, public, final ja abstract. Ne tarkoittavat.
Javan oliovirrat eli oliotiedostojen käsittely. Olio- eli objektitiedostojen käsittely Käsittely täysin samanlaista kuin muiden tiedostojen 1.Otetaan.
1 © Jukka Juslin Luokat, attribuutit ja metodit Yleistietoa: seuraavalla koulutusviikolla tarkempi käsittely.
14. Poikkeukset Sisällys Johdanto poikkeuksiin. Poikkeusten käsittely: − Poikkeusten käsittely paikallisesti. − Poikkeusten heittäminen. Exception.
15. Ohjelmoinnin tekniikkaa
16. Javan omat luokat Sisällys Johdanto. Object -luokka: − toString -, equals -, clone - ja getClass -metodit. Comparable -rajapinta: − compareTo.
Yksikkötestaus ● Yksikkötestauksella tarkoitetaan lähdekoodiin kuuluvien yksittäisten osien testaamista. Termi yksikkö viittaa ohjelman pienimpiin mahdollisiin.
5. Kapselointi.
11. Rajapinnat.
Poikkeustenkäsittelylohkot try-catch
3. Luokat, oliot ja metodit Java-kielessä (Lausekielinen ohjelmointi I ja II –kursseilla opitun kertausta.)
Rajapintaluokat Rajapintaluokka luettelee metodit, joille tulee löytyä toteutus asianomaisen rajapinnan toteuttavista luokista. Rajapintaluokka on siis.
14. Hyvä ohjelmointitapa.
6. Metodit.
13. Pakkaukset.
4. Attribuutit.
3. Attribuutit.
13. Pakkaukset.
4. Luokan testaus ja käyttö olion kautta
eli oliotiedostojen käsittely
Esityksen transkriptio:

Polymorfismi Sisältö Mitä on polymorfismi? Polymorfismi / viittausmuuttujien käyttö Polymorfismi / metodien kutsuminen Polymorfismin hyödyntämisen esimerkki Abstraktit luokat ja metodit Abstraktit luokat ja metodit : esimerkki Rajapintaluokka Rajapintaluokka : esimerkki Pakkaukset © Jukka Harju, 2005

Mitä on polymorfismi? Polymorfismi eli monimuotoisuus tarkoittaa seuraavaa: Kaikkia samaan luokkahierarkiaan kuuluvia luokkia käsitellään kuten yliluokkaa (luokkahierarkia = yliluokka ja kaikki siitä periytetyt luokat). Käytännön hyödyt polymorfismista: Ohjelmien laajennettavuus paranee, ohjelmaan voidaan lisätä uusia luokkia ilman muutoksia aiempaan ohjelmakoodiin. Saman tietorakenteen (esim. taulukko) kautta voidaan käsitellä eri luokkien olioita. © Jukka Harju, 2005

Polymorfismi / viittausmuuttujien käyttö Aiemmin viittausmuuttujan tyyppi on aina ollut olion luokan mukainen. Esim. Tietokone laite = new Tietokone(); Viittausmuuttujan tyyppi Polymorfismi mahdollistaa seuraavan: Määritellään viittausmuuttujan tyypiksi luokkahierarkian kantaluokka. Kantaluokaksi voi valita haluamansa luokan, luokkahierarkia lähtee kantaluokasta alaspäin (kantaluokka voi siis olla muunkin tyyppinen kuin Object). © Jukka Harju, 2005

Polymorfismi / viittausmuuttujien käyttö Esimerkki 1. Polymorfismi / viittausmuuttujien sallittuja käyttötapoja. public class TietokoneSovellus { public void kaynnistaSovellus(){ //tämä on tuttua… Kannettava laite = new Kannettava(); //mutta polymorfismin ansiosta voimme //tehdä myös näin: Tietokone laite = new Kannettava(); //tai jopa näin: Object laite1 = new Kannettava(); Object laite2 = new Tietokone(); } . . . } © Jukka Harju, 2005

Polymorfismi / viittausmuuttujien käyttö Edellä todettiin, että yliluokan tyyppisen viittausmuuttujan käyttö on mahdollista aliluokan oliolle. Tämä johtuu siitä, että aliluokan ja yliluokan olioiden välillä on “olla”-tyyppinen suhde: aliluokan olio on myös yliluokan olio, esim. kannettava tietokone on tietokone. Toisinpäin asia ei ole mahdollinen, eli aliluokan tyyppiseen viittausmuuttujaan ei voida sijoittaa viitettä yliluokan olioon! © Jukka Harju, 2005

Polymorfismi / viittausmuuttujien käyttö Esimerkki 2. Yritys viitata yliluokan olioon aliluokan tyyppisestä viittausmuuttujasta. Virhe! Ei mene käännöksestä läpi! public class TietokoneSovellus { public void kaynnistaSovellus(){ Kannettava laite = new Tietokone(); } . . . } © Jukka Harju, 2005

Polymorfismi Sisältö Mitä on polymorfismi? Polymorfismi / viittausmuuttujien käyttö Polymorfismi / metodien kutsuminen Polymorfismin hyödyntämisen esimerkki Abstraktit luokat ja metodit Abstraktit luokat ja metodit : esimerkki Rajapintaluokka Rajapintaluokka : esimerkki Pakkaukset © Jukka Harju, 2005

Polymorfismi / metodien kutsuminen Edellä todettiin, että yliluokan tyyppisen viittausmuuttujan käyttö on mahdollista aliluokan oliolle. Mitä tapahtuu, kun aliluokan oliolle kutsutaan metodia yliluokan tyyppisen viittausmuuttujan kautta? Java tukee polymorfismia  Java tutkii ajonaikana minkä luokan olioon viittausmuuttuja todellisuudessa viittaa. Kutsuttu metodi suoritetaan siitä luokasta, jonka olio on kyseessä. Edellä kuvattua toimintaa kutsutaan nimellä dynaaminen sidonta. © Jukka Harju, 2005

Polymorfismi / metodien kutsuminen Esimerkki 1. Tilanne jossa ei esiinny polymorfismia. Oletetaan että toString-metodi on toteutettu sekä luokkaan Tietokone että luokkaan Kannettava. public class TietokoneSovellus { public void kaynnistaSovellus(){ Kannettava laite = new Kannettava(); String laitetiedot = laite.toString(); } . . . } Viittausmuuttujan tyyppi on sama kuin olion luokka. Lienee intuitiivisestikin selvää että tässä kutsutaan luokassa Kannettava toteutettua toString-metodia. © Jukka Harju, 2005

Polymorfismi / metodien kutsuminen Esimerkki 2. Polymorfinen tilanne. Oletetaan että toString-metodi on toteutettu sekä luokkaan Tietokone että luokkaan Kannettava. public class TietokoneSovellus { public void kaynnistaSovellus(){ Tietokone laite = new Kannettava(); System.out.println(laite.toString()); } . . . } Viittausmuuttujan tyyppinä on yliluokka. Jos toString-metodi on toteutettu sekä luokkaan Tietokone että luokkaan Kannettava, niin kumpaa tässä kutsutaan? © Jukka Harju, 2005

Polymorfismi / metodien kutsuminen Esimerkki 3. Polymorfinen tilanne. Oletetaan että toString-metodia ei ole toteutettu luokkaan Tietokone, eikä myöskään luokkaan Kannettava. public class TietokoneSovellus { public void kaynnistaSovellus(){ Tietokone laite = new Kannettava(); System.out.println(laite.toString()); } . . . } Viittausmuuttujan tyyppinä on yliluokka. Minkä luokan toString-metodille tämä kutsu ohjautuu? © Jukka Harju, 2005

Polymorfismi / metodien kutsuminen Esimerkistä 3 havaitaan, että kutsuttua metodia etsitään aina ensinnä olion mukaisesta luokasta. Metodin on kuitenkin oltava määriteltynä myös viittausmuuttujan mukaisessa yliluokassa! Mikäli olion luokassa ei ole toteutettu kutsuttua metodia, etsitään sitä seuraavaksi luokkahierarkiassa yhtä tasoa ylempänä olevasta luokasta. Mikäli metodia ei löydy, päädytään lopulta etsimään (ja esimerkissä 3 myös käyttämään) Javan Object-luokan metodia. © Jukka Harju, 2005

Polymorfismi / metodien kutsuminen Esimerkki 4. Polymorfinen tilanne. Oletetaan että Kannettava-luokkaan on toteutettu metodi nimeltä tutkiAkkuaJaljella, jota ei kuitenkaan ole määritelty luokassa Tietokone. Virhe! Ei mene käännöksestä läpi, koska metodia tutkiAkkuaJaljella ei ole lainkaan määritettynä yliluokassa. public class TietokoneSovellus { public void kaynnistaSovellus(){ Tietokone laite = new Kannettava(); double akkuaJaljella = laite.tutkiAkkuaJaljella(); } . . . } © Jukka Harju, 2005

Polymorfismi / metodien kutsuminen Esimerkki 5. Polymorfinen tilanne. Oletetaan että Kannettava-luokkaan on toteutettu metodi toString, jota ei kuitenkaan ole toteutettu luokkaan Tietokone. public class TietokoneSovellus { public void kaynnistaSovellus(){ Tietokone laite = new Kannettava(); System.out.println(laite); } . . . } Tässä tapahtuu toString-metodin kutsu, saadaanko virheilmoituksia? Vastaus: Ohjelma toimii, koska toString-metodi on peritty Object-luokasta luokkaan Tietokone. © Jukka Harju, 2005

Polymorfismi / yhteenveto Yliluokan tyyppisen viittausmuuttujan käyttö on mahdollista aliluokan oliolle. Aliluokan metodien kutsuminen onnistuu yliluokan tyyppisen viittausmuuttujan kautta, kunhan kutsuttava metodi on määritelty myös yliluokassa. Yliluokan olioon ei voi viitata aliluokan tyyppisen viittaumuuttujan kautta. Aliluokan oliota voidaan käsitellä kuten yliluokan oliota. © Jukka Harju, 2005

Polymorfismi / esimerkki Toteutetaan palkanlaskentaohjelmisto polymorfismia hyödyntäen. Alussa vain yksi työntekijätyyppi: kuukausipalkkainen. Myöhemmin halutaan laajentaa ohjelmaa esim. tuntipalkkaisilla työntekijöillä. © Jukka Harju, 2005

Polymorfismi / esimerkki Alkutilanne oheisen luokkakaavion mukainen. Tyontekija-luokassa määritellään kaikille aliluokille yhteisen attribuutit ja metodit. Kuukausipalkkainen-luokassa lisätty tarvittava kuukausipalkka-attribuutti. © Jukka Harju, 2005

Polymorfismi / esimerkki Tyontekija-luokan Java-toteutus /**  * Tyontekija-luokka kuvaa työntekijöiden yhteiset  * ominaisuudet ja toiminnot  *  * @author Jukka Harju  */ public class Tyontekija {     private String etunimi;     private String sukunimi;     private String hetu;     public Tyontekija(String etunimi, String sukunimi, String hetu) {         setEtunimi(etunimi);         setSukunimi(sukunimi);         setHetu(hetu);     }     public String getEtunimi() {         return etunimi;     }     public void setEtunimi(String etunimi) {         if ((etunimi != null) && (etunimi.length() > 0)) {             this.etunimi = etunimi;         } else {             System.out.println("Etunimi " + etunimi + " ei ole sallittu!");         }     }      © Jukka Harju, 2005

Polymorfismi / esimerkki     public String getHetu() {         return hetu;     }     public void setHetu(String hetu) {         if ((etunimi != null) && (hetu.length() == 11)) {             this.hetu = hetu;         } else {             System.out.println("Hetu " + hetu + " ei ole sallittu!");         }     }     public String getSukunimi() {         return sukunimi;     }     public void setSukunimi(String sukunimi) {         if ((sukunimi != null) && (sukunimi.length() > 0)) {             this.sukunimi = sukunimi;         } else {             System.out.println("Sukunimi " + sukunimi + " ei ole sallittu!");         }     }     public String toString() {         return "Henkilo: " + etunimi + " " + sukunimi + ", hetu: " + hetu;     } } © Jukka Harju, 2005

Polymorfismi / esimerkki Kuukausipalkkainen-luokan Java-toteutus /**  * Kuukausipalkkainen-luokka kuvaa kuukausipalkkaisen  * työntekijän ominaisuudet ja toiminnot  *  * @author Jukka Harju  */ public class Kuukausipalkkainen extends Tyontekija {     private double kuukausipalkka;     public Kuukausipalkkainen(         String etunimi, String sukunimi, String hetu, double kuukausipalkka) {         super(etunimi, sukunimi, hetu);         setKuukausipalkka(kuukausipalkka);     }     public double getKuukausipalkka() {         return kuukausipalkka;     }     public void setKuukausipalkka(double kuukausipalkka) {         if (kuukausipalkka > 0) {             this.kuukausipalkka = kuukausipalkka;         } else {             System.out.println(                 "Kuukausipalkka " + kuukausipalkka + " ei ole sallittu!");         }     }     public String toString() {         return super.toString() + ", palkka: " + kuukausipalkka;     } } © Jukka Harju, 2005

Polymorfismi / esimerkki Polymorfismin hyödyntäminen sovellusluokassa. /**  * Sovellus hyödyntää monimuotoisuutta työntekijöiden käsittelemisessä.  *  * @author Jukka Harju  */ public class Palkkasovellus {     public void kaynnistaSovellus() {         //alustetaan henkilöstön tiedot         Tyontekija[] henkilosto = new Tyontekija[4];                  henkilosto[0] =             new Kuukausipalkkainen("Larry", "Brown", "010168-1112", 5500);         henkilosto[1] =             new Kuukausipalkkainen("Paul", "Anderson", "131175-5531", 7500);         henkilosto[2] =             new Kuukausipalkkainen("Mark", "Johnson", "010163-882A", 11800);         henkilosto[3] = new Tyontekija("Marty", "Hall", "020371-2234");         //tulostetaan koko henkilöstön tiedot         for (int i = 0; i < henkilosto.length; i++) {             if(henkilosto[i] != null) { System.out.println(henkilosto[i]); }         }     }     public static void main(String[] args) {         Palkkasovellus sovellus = new Palkkasovellus();         sovellus.kaynnistaSovellus();     } } © Jukka Harju, 2005

Polymorfismi / esimerkki Toteutetaan ohjelman laajennos: lisätään tuntipalkkainen työntekijä. Hyödynnetään laajentamisessa polymorfismia: luokkien Tyontekija ja Tuntipalkkainen koodia ei tarvitse mitenkään muuttaa. Myös sovelluksen tietyt osat (esimerkissämme tulostus) toimivat ilman että niitä tarvitsee lainkaan muuttaa. © Jukka Harju, 2005

Polymorfismi / esimerkki Tuntipalkkainen-luokan Java-toteutus. /**  * Tuntipalkkainen-luokka kuvaa tuntipalkkaisen  * työntekijän ominaisuudet ja toiminnot  *  * @author Jukka Harju  */ public class Tuntipalkkainen extends Tyontekija {     private double tuntipalkka;     private double tehdytTunnit;     public Tuntipalkkainen(         String etunimi, String sukunimi, String hetu, double tuntipalkka,         double tehdytTunnit) {         super(etunimi, sukunimi, hetu);         setTuntipalkka(tuntipalkka);         setTehdytTunnit(tehdytTunnit);     }     public double getTehdytTunnit() {         return tehdytTunnit;     }     © Jukka Harju, 2005

Polymorfismi / esimerkki     public void setTehdytTunnit(double tehdytTunnit) {         if ((tehdytTunnit > 0) && (tehdytTunnit <= (4 * 80))) {             this.tehdytTunnit = tehdytTunnit;         } else {             System.out.println(                 "Tunteja saa tehdä vain välillä 0-80 per viikko.");         }     }     public double getTuntipalkka() {         return tuntipalkka;     }     public void setTuntipalkka(double tuntipalkka) {         if (tuntipalkka > 0) {             this.tuntipalkka = tuntipalkka;         } else {             System.out.println(                 "Tuntipalkka " + tuntipalkka + " ei ole sallittu!");         }     }     public String toString() {         return super.toString() + ", tuntipalkka: " + tuntipalkka +         ", tehdyt tunnit: " + tehdytTunnit;     } } © Jukka Harju, 2005

Polymorfismi / esimerkki Laajennettu sovellus Javalla. /**  * Sovellus hyödyntää monimuotoisuutta työntekijöiden käsittelemisessä.  *  * @author Jukka Harju  */ public class Palkkasovellus {     public void kaynnistaSovellus() {         //alustetaan henkilöstön tiedot         Tyontekija[] henkilosto = new Tyontekija[4];         henkilosto[0] =             new Kuukausipalkkainen("Larry", "Brown", "010168-1112", 5500);         henkilosto[1] =             new Kuukausipalkkainen("Paul", "Anderson", "131175-5531", 7500);         henkilosto[2] =             new Tuntipalkkainen("Mark", "Johnson", "010163-882A", 45.5, 165);         henkilosto[3] = new Tyontekija("Marty", "Hall", "020371-2234");         //tulostetaan koko henkilöstön tiedot         for (int i = 0; i < henkilosto.length; i++) {             if(henkilosto[i] != null) { System.out.println(henkilosto[i]); }         }     }     public static void main(String[] args) {         Palkkasovellus sovellus = new Palkkasovellus();         sovellus.kaynnistaSovellus();     } } Ainoa tarvittava muutos on uuden työntekijätyypin käyttäminen olion luonnissa! © Jukka Harju, 2005

Polymorfismi Sisältö Mitä on polymorfismi? Polymorfismi / viittausmuuttujien käyttö Polymorfismi / metodien kutsuminen Polymorfismin hyödyntämisen esimerkki Abstraktit luokat ja metodit Abstraktit luokat ja metodit : esimerkki Rajapintaluokka Rajapintaluokka : esimerkki Pakkaukset © Jukka Harju, 2005

Abstrakti luokka Abstraktit luokka esiintyy aina yliluokkana. Abstraktista luokasta ei voida luoda oliota  abstraktia luokkaa käytetään aina siitä periytettyjen konkreettisten luokkien kautta. Abstraktissa luokassa toteutetaan vain aliluokille yhteisen komponentit, useimmiten abstraktit luokat eivät edes toimisi kunnolla vaikka niistä voisikin luoda olion. UML-luokkakaaviossa abstraktin luokan nimi kirjoitetaan kursiivilla. © Jukka Harju, 2005

Abstrakti luokka & Java Javassa abstrakti luokan määrittelyssä käytetään avainsanaa abstract. Abstrakti luokka sisältää tyypillisesti yhden tai useampia abstrakteja metodeja public abstract double laskeViikkopalkka(); Abstrakti metodi: Pelkkä metodin määrittely, ei sisällä lainkaan { }-merkkien sisään (metodilohkoon) tulevaan toteutusta. Abstraktit metodit täytyy korvata aliluokassa. © Jukka Harju, 2005

Esimerkki: Abstraktien luokkien ja metodien käyttö Tehtävä: luo palkkaohjelmisto Käytä abstrakteja metodeja ja polymorfismia. Ongelmanasettelu 2 työntekijätyyppiä, palkat maksetaan viikottain Kuukausipalkkainen (kiinteä palkka, työtunneilla ei väliä) Tuntipalkkainen (ylityö [>40 tuntia] maksetaan 1,5 –kertaisena) Esimerkin idea on lähteestä: Deitel & Deitel: Java How to Program, 5th edition © Jukka Harju, 2005

Esimerkki: Abstraktien luokkien ja metodien käyttö Toteutetaan yliluokkaan Tyontekija abstrakti metodi laskeViikkopalkka (palauttaa palkan) Yliluokassa Tyontekija on oltava määriteltynä metodi laskeViikkopalkka, sillä muutoin polymorfismia ei voida käyttää. Metodi on abstrakti koska palkka riippuu työntekijän tyypistä. Geneeriselle työntekijälle ei voida laskea palkkaa. Kielletään samalla Tyontekija-luokan olioiden luonti, koska jokaiselle työntekijälle on oltava tiedossa palkka  tehdään Tyontekija-luokasta abstrakti. © Jukka Harju, 2005

Esimerkki: Abstraktien luokkien ja metodien käyttö /**  * Tyontekija-luokka kuvaa työntekijöiden yhteiset  * ominaisuudet ja toiminnot  *  * @author Jukka Harju  */ public abstract class Tyontekija {     private String etunimi;     private String sukunimi;     private String hetu;     public Tyontekija(String etunimi, String sukunimi, String hetu) {         setEtunimi(etunimi);         setSukunimi(sukunimi);         setHetu(hetu);     } . .     public abstract double laskeViikkopalkka(); } Tyontekija-luokka määritelty abstraktiksi. Luokassa määritelty abstrakti metodi laskeViikkopalkka. © Jukka Harju, 2005

Esimerkki: Abstraktien luokkien ja metodien käyttö /**  * Kuukausipalkkainen-luokka kuvaa kuukausipalkkaisen  * työntekijän ominaisuudet ja toiminnot  *  * @author Jukka Harju  */ public class Kuukausipalkkainen extends Tyontekija {     private double kuukausipalkka; . . .     /**      * Metodi laskee ja palauttaa työntekijan kuukauden palkan.      *      * @return kuukausipalkka      */     public double laskeViikkopalkka() {         return kuukausipalkka / 4;     } } Kuukausipalkkainen-luokassa korvataan yliluokan abstrakti metodi laskeViikkopalkka. © Jukka Harju, 2005

Esimerkki: Abstraktien luokkien ja metodien käyttö /**  * Tuntipalkkainen-luokka kuvaa tuntipalkkaisen  * työntekijän ominaisuudet ja toiminnot  *  * @author Jukka Harju  */ public class Tuntipalkkainen extends Tyontekija {     private double tuntipalkka;     private double tehdytTunnit; . .     public double laskeViikkopalkka() {         double palkka = 0;         if (tehdytTunnit <= 40) {             palkka = tehdytTunnit * tuntipalkka;         } else {             palkka =                 palkka + (40 * tuntipalkka) +                 ((tehdytTunnit - 40) * 1.5 * tuntipalkka);         }         return palkka;     } } Tuntipalkkainen-luokassa korvataan yliluokan abstrakti metodi laskeViikkopalkka. Mahdollinen ylityö tulee huomioida. © Jukka Harju, 2005

Esimerkki: Abstraktien luokkien ja metodien käyttö public class Palkkasovellus2 {     public void kaynnistaSovellus() {         //alustetaan henkilöstön tiedot         Tyontekija[] henkilosto = new Tyontekija[4];         henkilosto[0] =             new Kuukausipalkkainen("Larry", "Brown", "010168-1112", 5500);         henkilosto[1] =             new Kuukausipalkkainen("Paul", "Anderson", "131175-5531", 7500);         henkilosto[2] =             new Tuntipalkkainen("Mark", "Johnson", "010163-882A", 100, 50);         //henkilosto[3] = new Tyontekija("Marty", "Hall", "020371-2234");                  //tulostetaan koko henkilöstön tiedot: nimi ja palkka ja viikkopalkka         for (int i = 0; i < henkilosto.length; i++) {             if (henkilosto[i] != null) {                 System.out.println(henkilosto[i]);                 System.out.println(                     "viikkopalkka = " + henkilosto[i].laskeViikkopalkka() +                     "\n");             }         }     }     public static void main(String[] args) {         Palkkasovellus2 sovellus = new Palkkasovellus2();         sovellus.kaynnistaSovellus();     } } Tyontekija-luokasta ei voida enää luoda oliota. Tulostetaan myös viikkopalkka. © Jukka Harju, 2005

Kertaus: final-metodit ja -luokat Ei voida korvata. private-metodit ovat implisiittisesti määriteltyjä final-tyyppisiksi. static-metodit ovat implisiittisesti määriteltyjä final-tyyppisiksi. final-luokat Eivät voi olla yliluokkana. final–luokkien metodit ovat implisiittisesti määriteltyjä final-tyyppisiksi. esim. luokka String final-attribuutit? © Jukka Harju, 2005

Polymorfismi Sisältö Mitä on polymorfismi? Polymorfismi / viittausmuuttujien käyttö Polymorfismi / metodien kutsuminen Polymorfismin hyödyntämisen esimerkki Abstraktit luokat ja metodit Abstraktit luokat ja metodit : esimerkki Rajapintaluokka Rajapintaluokka : esimerkki Pakkaukset © Jukka Harju, 2005

Rajapintaluokka Määrittely alkaa avainsanalla interface. Sisältää vain public abstract –tyyppisiä metodeja. Luokkien (jotka toteuttavat rajapinnan) täytyy toteuttaa ko metodit. Ei sisällä lainkaan attribuutteja. Luokat toteuttavat rajapinnan (ja sen metodit) avainsana implements: public class Tietokone implements Taltioitava © Jukka Harju, 2005

Rajapintaluokat UML luokkakaaviossa UML-luokkakaaviossa luokalla ei attribuutteja Luokan nimen edessä <<interface>>-merkintä. Rajapinnan toteuttaminen : nuolityyppi muuten kuten periytymisessä, mutta katkoviivalla. © Jukka Harju, 2005

Rajapintojen luominen ja käyttö Useiden rajapintojen toteuttaminen Toteutettavat rajapinnat luetellaan pilkulla eroteltuina avainsanan implements jälkeen. Vakiotiedot voidaan määritellä rajapintaa käyttäen public interface VAKIOT { public static final int YKSI = 1; public static final int KAKSI = 2; public static final int KOLME = 3; } © Jukka Harju, 2005

Esimerkki: Rajapintaluokan käyttö Rajapintaluokassa Taltioitava taltioitava määritellään metodit taltioiTiedot ja palautaTiedot, jotka tulee toteuttaa rajapinnan mukaisissa luokissa. /**  * Taltioitava-rajapinta määrittelee taltioitavalle  * oliolle pakolliset metodit.  *  * @author Jukka Harju  */ public interface Taltioitava {     public abstract String taltioiTiedot();     public abstract void palautaTiedot(String tiedot); } Rajapintaluokassa vain abstrakteja metodeja! © Jukka Harju, 2005

Esimerkki: Rajapintaluokan käyttö Luokka Tietokone toteuttaa rajapinnan Taltioitava. public class Tietokone implements Taltioitava {     private int muisti;     private String prosessori; ...      /**      * Taltioi attribuuttien arvot merkkijonoon      * '|'-merkillä eroteltuina.      *      * @return tiedot        Attribuuttien taltioidut arvot.      */     public String taltioiTiedot() {         String tiedot = muisti + "\r" + prosessori;         return tiedot;     }     /**      * Palauttaa arvot attribuuteille.      *      * @param tiedot        Merkkijono jossa palautettavat arvot      *                                         sijaitsevat.      */     public void palautaTiedot(String tiedot) {         if (tiedot != null) {             String[] attribuutit = tiedot.split("\r");             muisti = Integer.parseInt(attribuutit[0]);             prosessori = attribuutit[1];         } else {             System.out.println("Tietojen palautus ei onnistunut!");         }     } } Tässä kohden normaalisti set-, get- yms. metodit, esimerkistä näkyy vain osa. Luokkaan on toteutettava rajapinnan Taltioitava määräämät metodit. © Jukka Harju, 2005

Esimerkki: Rajapintaluokan käyttö Sovellus luo Tietokone-olion ja tallettaa sen tiedot tiedostoon. Tiedostosta tiedot palautetaan toiselle Tietokone-luokan oliolle. public class Taltiointisovellus {     private void aja() {         Tietokone omaKone = new Tietokone(2048, "Intel");         String omanKoneenTiedot = omaKone.taltioiTiedot();         /*          * Tähän koodi jossa tiedot kirjoitetaan tiedostoon!          */                  /*          * Tähän koodi jossa tiedot luetaan tiedostosta!          */         Tietokone palautettuOmaKone = new Tietokone();         palautettuOmaKone.palautaTiedot(omanKoneenTiedot);     }     public static void main(String[] args) {         Taltiointisovellus ohjelma = new Taltiointisovellus();         ohjelma.aja();     } } © Jukka Harju, 2005

Pakkaukset (packages) Pakkaukset ovat Javan keino suurien ohjelmistojen luokkien hallinnointiin. Samaan pakkaukseen kerätään samaan loogiseen kokonaisuuteen liittyviä luokkia. Pakkaus muodostaa kokonaisuuden ("nimiavaruus"), jonka sisällä näkyvät oletusarvoisesti vain muut saman pakkauksen luokat. Pakkaus johon luokka kuuluu määritellään luokkatiedoston alussa heti ensimmäisenä olevalla package-määreellä. Esim. package jha.db; //kaksitasoinen pakkaus public class ... © Jukka Harju, 2005

Pakkaukset (packages) Käyttöjärjestelmätasolla samaan pakkaukseen kuuluvat luokat täytyy sijoittaa samaan kansioon. IDE-ympäristöt kuten Eclipse hoitavat kansioihin sijoittamisen automaattisesti. Kääntäminen javac-komennolla täytyy tehdä sovelluksen "ylätasolla"! © Jukka Harju, 2005

Pakkaukset / näkyvyys Pakkauksen ulkopuolelta voidaan viitata pakkauksen sisällä oleviin julkisiin (public) luokkiin notaatiolla pakkauksenNimi.luokanNimi. Esim kutsutaan pakkauksen jha.db sisässä olevan luokan MySQL metodia connect. jha.db.MySQL.connect(); © Jukka Harju, 2005

Pakkaukset / näkyvyys tai Edellä olevaan tapaa järkevämpää on käytännössä lähes aina käyttää import-määrettä. import-määre kirjoitetaan luokkatiedoston alkuun heti mahdollisen package-määreen jälkeen. '*'-merkillä voidaan sallia kääntäjän tuoda kaikki ko pakkauksen tarvittavat luokat, suositeltavampaa on kuitenkin luetella vain tarvittavat luokat. Esim. package tietokantasovellus; import jha.db.*; public class ... tai import jha.db.MySQL; © Jukka Harju, 2005

Pakkaukset / nimeäminen Pakkaukset on suositeltu nimettäväksi käyttäen domain-nimestä johdettuja polkuja. Suositellulla nimeämiskäytännöllä vältytään mahdollisilta yhteentörmäyksiltä pakkausten nimissä. Edellä oli pakkaus jha.db; Suositeltavampi nimeämistapa olisi esim: fi.helia.jha.db; © Jukka Harju, 2005

Polymorfismi Sisältö Mitä on polymorfismi? Polymorfismi / viittausmuuttujien käyttö Polymorfismi / metodien kutsuminen Polymorfismin hyödyntämisen esimerkki Abstraktit luokat ja metodit Abstraktit luokat ja metodit : esimerkki Rajapintaluokka Rajapintaluokka : esimerkki Pakkaukset © Jukka Harju, 2005