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