Polymorfismi Sislt 1 2 3 4 5 6

  • Slides: 48
Download presentation
Polymorfismi Sisältö 1. 2. 3. 4. 5. 6. 7. 8. 9. Mitä on polymorfismi?

Polymorfismi Sisältö 1. 2. 3. 4. 5. 6. 7. 8. 9. Mitä on polymorfismi? Polymorfismi / viittausmuuttujien käyttö Polymorfismi / metodien kutsuminen Polymorfismin hyödyntämisen esimerkki Abstraktit luokat ja metodit : esimerkki Rajapintaluokka : esimerkki Pakkaukset © Jukka Harju, 2005 1

Mitä on polymorfismi? Polymorfismi eli monimuotoisuus tarkoittaa seuraavaa: • Kaikkia samaan luokkahierarkiaan kuuluvia luokkia

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 2

Polymorfismi / viittausmuuttujien käyttö • Aiemmin viittausmuuttujan tyyppi on aina ollut olion luokan mukainen.

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 3

Polymorfismi / viittausmuuttujien käyttö Esimerkki 1. Polymorfismi / viittausmuuttujien sallittuja käyttötapoja. public class Tietokone.

Polymorfismi / viittausmuuttujien käyttö Esimerkki 1. Polymorfismi / viittausmuuttujien sallittuja käyttötapoja. public class Tietokone. Sovellus { public void kaynnista. Sovellus(){ //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 laite 1 = new Kannettava(); Object laite 2 = new Tietokone(); } . . . } © Jukka Harju, 2005 4

Polymorfismi / viittausmuuttujien käyttö • Edellä todettiin, että yliluokan tyyppisen viittausmuuttujan käyttö on mahdollista

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 5

Polymorfismi / viittausmuuttujien käyttö Esimerkki 2. Yritys viitata yliluokan olioon aliluokan tyyppisestä viittausmuuttujasta. Virhe!

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

Polymorfismi Sisältö 1. 2. 3. 4. 5. 6. 7. 8. 9. Mitä on polymorfismi?

Polymorfismi Sisältö 1. 2. 3. 4. 5. 6. 7. 8. 9. Mitä on polymorfismi? Polymorfismi / viittausmuuttujien käyttö Polymorfismi / metodien kutsuminen Polymorfismin hyödyntämisen esimerkki Abstraktit luokat ja metodit : esimerkki Rajapintaluokka : esimerkki Pakkaukset © Jukka Harju, 2005 7

Polymorfismi / metodien kutsuminen • Edellä todettiin, että yliluokan tyyppisen viittausmuuttujan käyttö on mahdollista

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 8

Polymorfismi / metodien kutsuminen Esimerkki 1. Tilanne jossa ei esiinny polymorfismia. Oletetaan että to.

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

Polymorfismi / metodien kutsuminen Esimerkki 2. Polymorfinen tilanne. Oletetaan että to. String-metodi on toteutettu

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

Polymorfismi / metodien kutsuminen Esimerkki 3. Polymorfinen tilanne. Oletetaan että to. String-metodia ei ole

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

Polymorfismi / metodien kutsuminen • Esimerkistä 3 havaitaan, että kutsuttua metodia etsitään aina ensinnä

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 Objectluokan metodia. © Jukka Harju, 2005 12

Polymorfismi / metodien kutsuminen Esimerkki 4. Polymorfinen tilanne. Oletetaan että Kannettava-luokkaan on toteutettu metodi

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

Polymorfismi / metodien kutsuminen Esimerkki 5. Polymorfinen tilanne. Oletetaan että Kannettava-luokkaan on toteutettu metodi

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

Polymorfismi / yhteenveto • Yliluokan tyyppisen viittausmuuttujan käyttö on mahdollista aliluokan oliolle. • Aliluokan

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 15

Polymorfismi / esimerkki • Toteutetaan palkanlaskentaohjelmisto polymorfismia hyödyntäen. • Alussa vain yksi työntekijätyyppi: kuukausipalkkainen.

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 16

Polymorfismi / esimerkki • Alkutilanne oheisen luokkakaavion mukainen. • Tyontekija-luokassa määritellään kaikille aliluokille yhteisen

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

Polymorfismi / esimerkki • Tyontekija-luokan Java-toteutus /** * Tyontekija-luokka kuvaa työntekijöiden yhteiset * ominaisuudet

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) { set. Etunimi(etunimi); set. Sukunimi(sukunimi); set. Hetu(hetu); } public String get. Etunimi() { return etunimi; } public void set. Etunimi(String etunimi) { if ((etunimi != null) && (etunimi. length() > 0)) { this. etunimi = etunimi; } else { System. out. println("Etunimi " + etunimi + " ei ole sallittu!"); } } © Jukka Harju, 2005 18

Polymorfismi / esimerkki public String get. Hetu() { return hetu; } public void set.

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

Polymorfismi / esimerkki • Kuukausipalkkainen-luokan Java-toteutus /** * Kuukausipalkkainen-luokka kuvaa kuukausipalkkaisen * työntekijän ominaisuudet

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); set. Kuukausipalkka(kuukausipalkka); } public double get. Kuukausipalkka() { return kuukausipalkka; } public void set. Kuukausipalkka(double kuukausipalkka) { if (kuukausipalkka > 0) { this. kuukausipalkka = kuukausipalkka; } else { System. out. println( "Kuukausipalkka " + kuukausipalkka + " ei ole sallittu!"); } } public String to. String() { return super. to. String() + ", palkka: " + kuukausipalkka; } } © Jukka Harju, 2005 20

Polymorfismi / esimerkki • Polymorfismin hyödyntäminen sovellusluokassa. /** * Sovellus hyödyntää monimuotoisuutta työntekijöiden käsittelemisessä.

Polymorfismi / esimerkki • Polymorfismin hyödyntäminen sovellusluokassa. /** * Sovellus hyödyntää monimuotoisuutta työntekijöiden käsittelemisessä. * * @author Jukka Harju */ public class Palkkasovellus { public void kaynnista. Sovellus() { //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 -882 A", 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 = new Palkkasovellus(); sovellus. kaynnista. Sovellus(); } } © Jukka Harju, 2005 21

Polymorfismi / esimerkki • • Toteutetaan ohjelman laajennos: lisätään tuntipalkkainen työntekijä. Hyödynnetään laajentamisessa polymorfismia:

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 22

Polymorfismi / esimerkki • Tuntipalkkainen-luokan Java-toteutus. /** * Tuntipalkkainen-luokka kuvaa tuntipalkkaisen * työntekijän ominaisuudet

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 tehdyt. Tunnit; public Tuntipalkkainen( String etunimi, String sukunimi, String hetu, double tuntipalkka, double tehdyt. Tunnit) { super(etunimi, sukunimi, hetu); set. Tuntipalkka(tuntipalkka); set. Tehdyt. Tunnit(tehdyt. Tunnit); } public double get. Tehdyt. Tunnit() { return tehdyt. Tunnit; } © Jukka Harju, 2005 23

Polymorfismi / esimerkki public void set. Tehdyt. Tunnit(double tehdyt. Tunnit) { if ((tehdyt. Tunnit

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

Polymorfismi / esimerkki • Laajennettu sovellus Javalla. /** * Sovellus hyödyntää monimuotoisuutta työntekijöiden käsittelemisessä.

Polymorfismi / esimerkki • Laajennettu sovellus Javalla. /** * Sovellus hyödyntää monimuotoisuutta työntekijöiden käsittelemisessä. * * @author Jukka Harju */ public class Palkkasovellus { public void kaynnista. Sovellus() { //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 -882 A", 45. 5, 165); henkilosto[3] = new Tyontekija("Marty", "Hall", "020371 -2234"); Ainoa tarvittava muutos on uuden työntekijätyypin käyttäminen olion luonnissa! //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 = new Palkkasovellus(); sovellus. kaynnista. Sovellus(); } © Jukka Harju, } 2005 25

Polymorfismi Sisältö 1. 2. 3. 4. 5. 6. 7. 8. 9. Mitä on polymorfismi?

Polymorfismi Sisältö 1. 2. 3. 4. 5. 6. 7. 8. 9. Mitä on polymorfismi? Polymorfismi / viittausmuuttujien käyttö Polymorfismi / metodien kutsuminen Polymorfismin hyödyntämisen esimerkki Abstraktit luokat ja metodit : esimerkki Rajapintaluokka : esimerkki Pakkaukset © Jukka Harju, 2005 26

Abstrakti luokka • Abstraktit luokka esiintyy aina yliluokkana. • Abstraktista luokasta ei voida luoda

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 27

Abstrakti luokka & Java • Javassa abstrakti luokan määrittelyssä käytetään avainsanaa abstract. • Abstrakti

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 laske. Viikkopalkka(); • 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 28

Esimerkki: Abstraktien luokkien ja metodien käyttö • Tehtävä: luo palkkaohjelmisto – Käytä abstrakteja metodeja

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, 5 th edition © Jukka Harju, 2005 29

Esimerkki: Abstraktien luokkien ja metodien käyttö • Toteutetaan yliluokkaan Tyontekija abstrakti metodi laske. Viikkopalkka

Esimerkki: Abstraktien luokkien ja metodien käyttö • Toteutetaan yliluokkaan Tyontekija abstrakti metodi laske. Viikkopalkka (palauttaa palkan) – Yliluokassa Tyontekija on oltava määriteltynä metodi laske. Viikkopalkka, 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 30

Esimerkki: Abstraktien luokkien ja metodien käyttö /** * Tyontekija-luokka kuvaa työntekijöiden yhteiset * ominaisuudet

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

Esimerkki: Abstraktien luokkien ja metodien käyttö /** * Kuukausipalkkainen-luokka kuvaa kuukausipalkkaisen * työntekijän ominaisuudet

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. Kuukausipalkkainen * luokassa korvataan yliluokan * @return kuukausipalkka abstrakti metodi */ public double laske. Viikkopalkka() { laske. Viikkopalkka. return kuukausipalkka / 4; } } © Jukka Harju, 2005 32

Esimerkki: Abstraktien luokkien ja metodien käyttö /** * Tuntipalkkainen-luokka kuvaa tuntipalkkaisen * työntekijän ominaisuudet

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 tehdyt. Tunnit; . . . public double laske. Viikkopalkka() { double palkka = 0; Tuntipalkkainen-luokassa korvataan yliluokan abstrakti metodi laske. Viikkopalkka. if (tehdyt. Tunnit <= 40) { palkka = tehdyt. Tunnit * tuntipalkka; } else { palkka = palkka + (40 * tuntipalkka) + ((tehdyt. Tunnit - 40) * 1. 5 * tuntipalkka); } Mahdollinen ylityö tulee huomioida. return palkka; } } © Jukka Harju, 2005 33

Esimerkki: Abstraktien luokkien ja metodien käyttö public class Palkkasovellus 2 { public void kaynnista.

Esimerkki: Abstraktien luokkien ja metodien käyttö public class Palkkasovellus 2 { public void kaynnista. Sovellus() { //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 -882 A", 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]. laske. Viikkopalkka() + "n"); } } Tyontekijaluokasta ei voida enää luoda oliota. Tulostetaan myös viikkopalkka. public static void main(String[] args) { Palkkasovellus 2 sovellus = new Palkkasovellus 2(); sovellus. kaynnista. Sovellus(); } } © Jukka Harju, 2005 34

Kertaus: final-metodit ja -luokat • final-metodit – Ei voida korvata. – private-metodit ovat implisiittisesti

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

Polymorfismi Sisältö 1. 2. 3. 4. 5. 6. 7. 8. 9. Mitä on polymorfismi?

Polymorfismi Sisältö 1. 2. 3. 4. 5. 6. 7. 8. 9. Mitä on polymorfismi? Polymorfismi / viittausmuuttujien käyttö Polymorfismi / metodien kutsuminen Polymorfismin hyödyntämisen esimerkki Abstraktit luokat ja metodit : esimerkki Rajapintaluokka : esimerkki Pakkaukset © Jukka Harju, 2005 36

Rajapintaluokka • Määrittely alkaa avainsanalla interface. • Sisältää vain public abstract –tyyppisiä metodeja. •

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 37

Rajapintaluokat UML luokkakaaviossa • • • UML-luokkakaaviossa luokalla ei attribuutteja Luokan nimen edessä <<interface>>-merkintä.

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

Rajapintojen luominen ja käyttö • Useiden rajapintojen toteuttaminen – Toteutettavat rajapinnat luetellaan pilkulla eroteltuina

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 39

Esimerkki: Rajapintaluokan käyttö • Rajapintaluokassa Taltioitava taltioitava määritellään metodit taltioi. Tiedot ja palauta. Tiedot,

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

Esimerkki: Rajapintaluokan käyttö Luokka Tietokone toteuttaa rajapinnan Taltioitava. public class Tietokone implements Taltioitava {

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 taltioi. Tiedot() { String tiedot = muisti + "r" + prosessori; Tässä kohden normaalisti set-, get - yms. metodit, esimerkistä näkyy vain osa. return tiedot; } /** * Palauttaa arvot attribuuteille. * * @param tiedot Merkkijono jossa palautettavat arvot * sijaitsevat. */ public void palauta. Tiedot(String tiedot) { if (tiedot != null) { String[] attribuutit = tiedot. split("r"); muisti = Integer. parse. Int(attribuutit[0]); prosessori = attribuutit[1]; } else { System. out. println("Tietojen palautus ei onnistunut!"); } } © Jukka Harju, 2005 } Luokkaan on toteutettava rajapinnan Taltioitava määräämät metodit. 41

Esimerkki: Rajapintaluokan käyttö Sovellus luo Tietokone-olion ja tallettaa sen tiedot tiedostoon. Tiedostosta tiedot palautetaan

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 oma. Kone = new Tietokone(2048, "Intel"); String oman. Koneen. Tiedot = oma. Kone. taltioi. Tiedot(); /* * Tähän koodi jossa tiedot kirjoitetaan tiedostoon! */ /* * Tähän koodi jossa tiedot luetaan tiedostosta! */ Tietokone palautettu. Oma. Kone = new Tietokone(); palautettu. Oma. Kone. palauta. Tiedot(oman. Koneen. Tiedot ); } public static void main(String[] args) { Taltiointisovellus ohjelma = new Taltiointisovellus(); ohjelma. aja(); } } © Jukka Harju, 2005 42

Pakkaukset (packages) • • Pakkaukset ovat Javan keino suurien ohjelmistojen luokkien hallinnointiin. Samaan pakkaukseen

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 43

Pakkaukset (packages) • • • Käyttöjärjestelmätasolla samaan pakkaukseen kuuluvat luokat täytyy sijoittaa samaan kansioon.

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 44

Pakkaukset / näkyvyys • • Pakkauksen ulkopuolelta voidaan viitata pakkauksen sisällä oleviin julkisiin (public)

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

Pakkaukset / näkyvyys • Edellä olevaan tapaa järkevämpää on käytännössä lähes aina käyttää import-määrettä.

Pakkaukset / näkyvyys • 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 package tietokantasovellus; import jha. db. My. SQL; public class. . . © Jukka Harju, 2005 46

Pakkaukset / nimeäminen • • • Pakkaukset on suositeltu nimettäväksi käyttäen domain-nimestä johdettuja polkuja.

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 47

Polymorfismi Sisältö 1. 2. 3. 4. 5. 6. 7. 8. 9. Mitä on polymorfismi?

Polymorfismi Sisältö 1. 2. 3. 4. 5. 6. 7. 8. 9. Mitä on polymorfismi? Polymorfismi / viittausmuuttujien käyttö Polymorfismi / metodien kutsuminen Polymorfismin hyödyntämisen esimerkki Abstraktit luokat ja metodit : esimerkki Rajapintaluokka : esimerkki Pakkaukset © Jukka Harju, 2005 48