Alkuehdot. Motivointi (1/2) Ohjelmointi II, kevät 2004 Kuopion yliopisto. Motivointi (2/2) (C) Mauno Rönkkö. Mitä tekee kutsupieninalkio(t, 10)?

Samankaltaiset tiedostot
JAVA-OHJELMOINTI 3 op A274615

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

14. Poikkeukset 14.1

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

Rajapinta (interface)

Java-API, rajapinnat, poikkeukset, UML,...

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

14. Poikkeukset 14.1

Olio-ohjelmointi Käyttöliittymä

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Poikkeukset ja tietovirrat: Virhetilanteiden ja syötevirtojen käsittely

Listarakenne (ArrayList-luokka)

Poikkeustenkäsittely

Olio-ohjelmointi Javalla

Ohjelmoinnin jatkokurssi, kurssikoe

16. Javan omat luokat 16.1

9. Periytyminen Javassa 9.1

GRAAFISEN KÄYTTÖLIITTYMÄN OHJELMOINTI JAVA SWING

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

9. Periytyminen Javassa 9.1

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

15. Ohjelmoinnin tekniikkaa 15.1

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

Sisältö. 2. Taulukot. Yleistä. Yleistä

Sisältö. 22. Taulukot. Yleistä. Yleistä

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

1. Omat operaatiot 1.1

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

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

1 Tehtävän kuvaus ja analysointi

Rinnakkaisohjelmointi kurssi. Opintopiiri työskentelyn raportti

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

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

Pino S on abstrakti tietotyyppi, jolla on ainakin perusmetodit:

Sisältö. Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 6.2

Java UI-komponentit (JTable) Juha Järvensivu 2007

Ohjelmointi 2 / 2008 Välikoe / Pöytätestaa seuraava ohjelma.

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Tietorakenneluokkia 2: HashMap, TreeMap

Sisältö Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 26.2

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

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

15. Ohjelmoinnin tekniikkaa 15.1

Java kahdessa tunnissa. Jyry Suvilehto

20. Javan omat luokat 20.1

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

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

Graafinen käyttöliittymä, osa 2

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

1.3Lohkorakenne muodostetaan käyttämällä a) puolipistettä b) aaltosulkeita c) BEGIN ja END lausekkeita d) sisennystä

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

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes)

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo

Sisältö. Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 6.2

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

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

Mitä poikkeuskäsittely tarkoittaa?

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

Java-kielen perusteet

Sisällys. 11. Rajapinnat. Johdanto. Johdanto

Tietojen syöttäminen ohjelmalle. Tietojen syöttäminen ohjelmalle Scanner-luokan avulla

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. X Poikkeusten käsittelystä

OutputStream ja InputStream. Tietovirrat ja niiden suunnat. Tietovirtojen käyttö. FileInputStream esimerkki. DataOutputStream ja DataInputStream

Ohjelmointi 2 / 2010 Välikoe / 26.3

Java ja grafiikka. Ville Sundberg

Olio-ohjelmointi Virhetilanteiden käsittely

17. Javan omat luokat 17.1

Osio 4: Graafinen käyttöliittymä

Javan perusteita. Janne Käki

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

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

Ohjelmoinnin perusteet Y Python

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

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

Mikä yhteyssuhde on?

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

Ohjelmointityö 3. Mikko Laamanen

Periytyminen (inheritance)

12. Näppäimistöltä lukeminen 12.1

7. Oliot ja viitteet 7.1

Metodit Arvotyyppi. Metodit Arvotyyppi. Metodit Parametrit. Metodit Parametrit. Metodit Kuormittaminen. Metodit Kuormittaminen. Javan perusteet

Ohjelmoinnin perusteet, kurssikoe

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

Rutiinin muodostaminen. 2. Rutiinin muodostaminen. specification) Määrittely (specification( Määrittelyn osapuolet. Hyvän ohjelman tunnusmerkit

815338A Ohjelmointikielten periaatteet

Tietorakenteet. JAVA-OHJELMOINTI Osa 5: Tietorakenteita. Sisällys. Merkkijonot (String) Luokka String. Metodeja (public)

Luokan sisällä on lista

Luento 6. T Ohjelmoinnin jatkokurssi T1 & T Ohjelmoinnin jatkokurssi L1. Luennoitsija: Otto Seppälä

Tietokannat II -kurssin harjoitustyö

17. Javan omat luokat 17.1

1.3 Lohkorakenne muodostetaan käyttämällä a) puolipistettä b) aaltosulkeita c) BEGIN ja END lausekkeita d) sisennystä

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

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

Olio-ohjelmointi Syntaksikokoelma

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

ITKP102 Ohjelmointi 1 (6 op)

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

List-luokan soveltamista. Listaan lisääminen Listan läpikäynti Listasta etsiminen Listan sisällön muuttaminen Listasta poistaminen Listan kopioiminen

Ohjelmoinnin perusteet Y Python

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

Transkriptio:

Ohjelmointi II, kevät 2004 Kuopion yliopisto (C) Mauno Rönkkö (Kalvot tarkoitettu itseopiskelun tueksi. Muu käyttö kielletty ilman lupaa.) Motivointi (1/2) int pieninalkio (int[] t, int l) //palauttaa t:n pienimmän alkion tarkasteltaessa //t:tä aina l:nteen alkioon asti int s, i; s=t[0]; for (i=0; i<l; i=i+1) if (t[i]<s) s=t[i]; return s Mitä tekee kutsupieninalkio(t, 10)? Alkuehdot Motivointi (2/2) int pieninalkio (int[] t, int l) //palauttaa t:n pienimmän alkion tarkasteltaessa //t:tä aina l:nteen alkioon asti //PRE: 0<l && l<=t.length int s, i; s=t[0]; for (i=0; i<l; i=i+1) if (t[i]<s) s=t[i]; return s; Nyt kommentissa sanotaan, millä l:n arvoilla kutsu on sallittu. Esim. pieninalkio(t, 10) ei ole sallittu. 1

Alkuehto ja sen tarkoitus Alkuehto kuvaa, millä parametrin arvoilla metodin kutsu on sallittu ja tuottaa halutun tuloksen. Javalla alkuehto joudutaan kirjoittamaan kommentiksi. Esimerkiksi: int pieninalkio (int[] t, int l) //palauttaa t:n pienimmän alkion tarkasteltaessa //t:tä aina l:nteen alkioon asti //PRE: 0<l && l<=t.length Metodin kutsujan huolehdittavaksi jää alkuehdon tarkistus ennen metodin kutsua. Esimerkiksi: if((0<l) && (l<=t.length)) System.out.println (pieninalkio(t,l)); Motivointi (1/2) int pieninalkio (int[] t, int l) //palauttaa t:n pienimmän alkion tarkasteltaessa //t:tä aina l:nteen alkioon asti //PRE: 0<l && l<=t.length int s, i; s=suurin(); for (i=0; i<l; i=seuraava(i)) s=pienin(s,t,i); return s; Mitä tekee kutsupieninalkio(t,3)? Loppuehdot Motivointi (2/2) int pieninalkio (int[] t, int l) //palauttaa t:stä pienimmän alkion //PRE: 0<l && l<=t.length //POST: pieninalkio(t,l)=min(t[0],t[1],t[l 1]) int s, i; s=suurin(); for (i=0; i<l; i=seuraava(i)) s=pienin(s,t,i); return s; Nyt kommentissa sanotaan, mitä metodi itseasiassa palauttaa. Samalla metodin sanallinen selitys yksinkertaistuu. 2

Loppuehto ja sen tarkoitus Loppuehto on ehto, joka on voimassa metodin suorituksen jälkeen. Loppuehto kuvaa yksiselitteisesti metodin toimintaa. Javalla loppuehto kirjoitetaan kommentiksi. Esimerkiksi: int pieninalkio (int[] t, int l) //palauttaa t:stä pienimmän alkion //PRE: 0<l && l<=t.length //POST: pieninalkio(t,l)=min(t[0],t[1],t[l 1]) Motivointi (1/3) String s; Integer i; i=integer.valueof(s); Metodin kutsuja voi luottaa, että loppuehto on voimassa metodin kutsun jälkeen. Entä, joss== Hello World? Motivointi (2/3) Poikkeukset public static Integer valueof(string s) throws NumberFormatException Returns a new Integer object initialized to the value of the specified String. Parameters: s the string to be parsed. Returns: a newly constructed Integer initialized to the value represented by the string argument. Throws: NumberFormatException if the string cannot be parsed as an integer. (Sun:1.3 API) 3

String s; Integer i; try Motivointi (3/3) i=integer.valueof(s); // Kaikki kunnossa. catch (NumberFormatException e) // Jotain pielessä! Esimerkki 1 import java.io.*; class PoikkeusEsimerkki public static void main (String[] a) try int i; String s; BufferedReader br; InputStreamReader isr; isr=new InputStreamReader(System.in); br=new BufferedReader(isr); System.out.println ("Kirjoita luku ja paina ENTER!"); s=br.readline(); i=integer.valueof(s); System.out.println ("Kirjoitit luvun: "+i); catch (NumberFormatException nfe) System.out.println ("Et antanut lukua!"); catch (IOException ioe) System.out.println ("IO VIRHE!"); Poikkeuksen tarkistaminen yleisesti try // Koodi, jota yritetään ajaa catch (XXXException exxx) // Poikkeuksen XXX käsittely catch (YYYException eyyy) // Poikkeuksen YYY käsittely catch finally // Koodi, joka suoritetaan aina Esimerkki 2 import java.io.*; class PoikkeusEsimerkki public static int lueluku() throws IOException try InputStreamReader isr=new InputStreamReader(System.in); BufferedReader br=new BufferedReader(isr); System.out.println ("Kirjoita luku ja paina ENTER!"); return Integer.valueOf(br.readLine()); catch (NumberFormatException nfe) System.out.println ("Et antanut lukua!"); public static void main (String[] a) try System.out.println ("Kirjoita luku ja paina ENTER!"); System.out.println ("Kirjoitit luvun: "+lueluku()); catch (IOException ioe) System.out.println ("IO VIRHE!"); 4

HUOM! HUOM! Poikkeuksien nostamisesta 2/3 1. Poikkeuksissa ohjelmakoodin suoritus hyppää => poikkeuksia käytettävä hillitysti ja harkiten 2. Poikkeukset ilmoittavat epätavallisesta toiminnasta => poikkeuksilla EI saa välittää normaaleja paluuarvoja 3. Jos poikkeusta ei käsitellä, Java käsittelee sen itse => ohjelman suoritus lopetetaan ja kutsupino tulostetaan Metodin on ilmoitettava mitä poikkeuksia se saattaa nostaa, lukuunottamattaruntimeexception tyyppisiä poikkeuksia. Esimerkiksi: void a (int b) throws IOException if (b<0) throw new IOException(); else throw new ArithmeticException(); Poikkeuksien nostamisesta 1/3 Poikkeuksien nostamisesta 3/3 Kun poikkeus nostetaan: luodaan uusithrowable luokan tai sen aliluokan olio välitetään sethrow käskyllä lähimmällecatch lohkolle Esimerkiksi: try throw new ArithmeticException(); catch (ArithmeticException earithmetic) //Siepataan poikkeus Kaikki nostettavat poikkeukset luetellaan metodin määrittelyssä (lukuunottamattaruntimeexception tyyppisiä poikkeuksia): void a (int b) throws IOException,XXException,YYException, 5

Oliot String omistaja double saldo Olion toiminta abc_456 "O.Mistaja" 10 110 0 +void talleta(double summa) +void nosta(string kuka,double summa) throws EiOmistaja,EiRahaa +double saldo(string kuka) abc_456.talleta(100) abc_456.nosta("v.aras", 50) > EiOmistaja abc_456.nosta("o.mistaja", 150) > EiRahaa abc_456.saldo("o.mistaja") > 110 abc_456.nosta("o.mistaja",110) Esimerkki: pankkitili abc_456 Oliot ovat yksilöitä Pankkitili "abc_456" pitää kirjaa tilin omistajasta ja tilisaldosta. Pankkitilile voi tallettaa rahaa kuka vaan, mutta vain omistaja saa nostaa rahaa tililtään. Omistajakaan ei saa nostaa tililtä enempää rahaa kuin mitä siellä on. Siksi omistaja saakin myös tiedustella saldon suuruuden. String omistaja double saldo abc_456 "O.Mistaja" 10 110 +void talleta(double summa) +void nosta(string kuka,double summa) throws EiOmistaja,EiRahaa +double saldo(string kuka) String omistaja double saldo abc_457 "T.Oinen" 170 +void talleta(double summa) +void nosta(string kuka,double summa) throws EiOmistaja,EiRahaa +double saldo(string kuka) String omistaja double saldo abc_456 +void talleta(double summa) +void nosta(string kuka, double summa) throws EiOmistaja,EiRahaa +double saldo(string kuka) abc_456.talleta(100) abc_457.nosta("o.mistaja", 50) > EiOmistaja abc_456.saldo("o.mistaja") > 110 abc_457.saldo("t.oinen") > 170 6

Ylikuormitus Lyhyesti String omistaja double saldo abc_456 +void talleta(double summa) +void talleta(double valuuttaa, double kurssi) +void nosta(string kuka, double summa) throws EiOmistaja,EiRahaa +double saldo(string kuka) Olioiden "tyyppiä" sanotaan luokaksi. Jokainen olio kuuluu siis johonkin luokkaan. Luokassa määritetään mitä tietoa olio pitää sisällään ja millä metodeilla päästään käsiksi tähän tietoon. Lisäksi luokassa annetaan alustajat, joilla olio luodaan. Ylikuormittavien metodien täytyy poiketa parametreiltään (joskin palautustyyppi voi olla eri)! Luokan osat Luokat olion attribuutit alustaja muuttajat String omistaja double saldo Pankkitili luokan nimi +Pankkitili(String omistaja,double saldo) +void talleta(double summa) +void nosta(string kuka, double summa) throws EiOmistaja,EiRahaa +double saldo(string kuka) havainnoija 7

String omistaja double saldo Luokka Javassa Pankkitili +Pankkitili(String omistaja,double saldo) +void talleta(double summa) +void nosta(string kuka, double summa) throws EiOmistaja,EiRahaa +double saldo(string kuka) class Pankkitili double saldo Luokka Javassa +Pankkitili(String omistaja,double saldo) +void talleta(double summa) +void nosta(string kuka, double summa) throws EiOmistaja,EiRahaa +double saldo(string kuka) class Pankkitili private String omistaja; private double saldo; String omistaja double saldo Luokka Javassa +Pankkitili(String omistaja,double saldo) +void talleta(double summa) +void nosta(string kuka, double summa) throws EiOmistaja,EiRahaa +double saldo(string kuka) class Pankkitili private String omistaja; Luokka Javassa +Pankkitili(String omistaja,double saldo) +void talleta(double summa) +void nosta(string kuka, double summa) throws EiOmistaja,EiRahaa +double saldo(string kuka) class Pankkitili private String omistaja; private double saldo; public Pankkitili (String omistaja, double saldo) this.omistaja=omistaja; this.saldo=saldo; 8

Luokka Javassa +void talleta(double summa) +void nosta(string kuka, double summa) throws EiOmistaja,EiRahaa +double saldo(string kuka) class Pankkitili private String omistaja; private double saldo; public Pankkitili (String omistaja, double saldo) this.omistaja=omistaja; this.saldo=saldo; public void talleta (double summa) this.saldo=this.saldo+summa; Luokka Javassa +double saldo(string kuka) class Pankkitili private String omistaja; private double saldo; public Pankkitili (String omistaja, double saldo) this.omistaja=omistaja; this.saldo=saldo; public void talleta (double summa) this.saldo=this.saldo+summa; public void nosta (String kuka, double summa) throws EiOmistaja, Ei Rahaa if (!kuka.equals(omistaja))throw new EiOmistaja(); else if (saldo<summa) throw new EiRahaa() else saldo=saldo summa; public double saldo(string kuka) return kuka.equals(this.omistaja)? this.saldo : 0.0; Luokka Javassa +void nosta(string kuka, double summa) throws EiOmistaja,EiRahaa +double saldo(string kuka) class Pankkitili private String omistaja; private double saldo; public Pankkitili (String omistaja, double saldo) this.omistaja=omistaja; this.saldo=saldo; public void talleta (double summa) this.saldo=this.saldo+summa; public void nosta (String kuka, double summa) throws EiOmistaja, Ei Rahaa if (!kuka.equals(omistaja))throw new EiOmistaja(); else if (saldo<summa) throw new EiRahaa() else saldo=saldo summa; class Pankkitili private String omistaja; private double saldo; Luokka Javassa public Pankkitili (String omistaja, double saldo) this.omistaja=omistaja; this.saldo=saldo; public void talleta (double summa) this.saldo=this.saldo+summa; public void nosta (String kuka, double summa) throws EiOmistaja, Ei Rahaa if (!kuka.equals(omistaja))throw new EiOmistaja(); else if (saldo<summa) throw new EiRahaa() else saldo=saldo summa; public double saldo(string kuka) return kuka.equals(this.omistaja)? this.saldo : 0.0; 9

Luokasta olioksi String omistaja double saldo Pankkitili +Pankkitili(String omistaja,double saldo) +void talleta(double summa) +void nosta(string kuka, double summa) throws EiOmistaja,EiRahaa +double saldo(string kuka) Pankkitili abc_456; abc_456=new Pankkitili ("O.Mistaja",110); abc_456.nosta("v.aras", 50) abc_456.nosta("o.mistaja", 150) > EiRahaa abc_456.saldo("o.mistaja") abc_456.nosta("o.mistaja",110) > EiOmistaja > 110 Suojausmääreet Pääluokka Javassa Julkinen:public class Paaohjelma public static void main (String[] argumentit) Pankkitili abc_456; abc_456=new Pankkitili ("O.Mistaja",100); System.out.println(abc_456.saldo("O.Mistaja")); Julkisen attribuutin arvoa voivat kaikki lukea ja muuttaa; julkista metodia voi kutsua kuka tahansa => julkinen attribuutti = synkrooninen kommunikointimuuttuja => julkinen attribuutti altistaa olion ulkopuolisille virheille => attribuutti ei saisi olla juuri koskaan julkinen 10

Paketoitu: (ei avainsanaa) Yksityinen:private Paketoidun attribuutin arvoa voi lukea ja muuttaa kaikki samaan pakettiin kuuluvat luokat (ja oliot); paketoitua metodia saavat kutsua kaikki saman paketin luokat ja oliot. => paketoitu attribuutti altistaa olion ulkopuolisille virheille => attribuutti ei saisi olla juuri koskaan paketoitu => julistamalla metodi paketoiduksi, estetään sen käyttö paketin ulkopuolelta => metodin käyttöä ei tarvitse selittää paketin käyttäjille riittää, että paketin toteuttajat tietävät sen toiminnan Yksityisen attribuutin arvoa voivat lukea ja muuttaa vain kaikki saman luokan rutiinit (ja oliot); sama pätee yksityisiin metodeihin. => jokaisen attribuutin tulisi olla yksityinen => yksityinen metodi on apumetodi, jonka käyttö edellyttä luokan sisäisen rakenteen tuntemusta Periytyvä:protected Periytyvän attribuutin arvoa voivat lukea ja muuttaa kaikki saman luokan rutiinit (ja oliot) ja siitä periytyvät luokat (ja oliot); saman pätee periytyviin metodeihin. => periytyvä attribuutti on luokan sisäinen attribuutti, joka sitoo rutiineita, mutta jonka käyttöä perilliset saattavat haluta muuttaa Erikoismääreet => periytyvä metodi on tyypillisesti sellainen, jonka jokainen perillinen toteuttaa eri tavalla 11

Luokka attribuutti:static Vakio:final static attribuutti on ns. luokka attribuutti : => kaikki saman luokan oliot jakavat luokka attribuutin keskenään => luokka attribuuttia ei missään nimessä voi käyttää olion identifioimiseen final attribuutti on vakio, eli sen arvon voi asettaa vain kerran: => vakion arvo asetetaan joko määrittelyn yhteydessä tai oliota luotaessa => vakiota ei missään nimessä voi käyttää olion identifioimiseen 1. Luokka attribuutti:static Vakio:final class classainoalaskuri class classlaskija // // // // static int intarvo; AinoaLaskuri a, a, b; b; public void voidtik(); //a.arvo==1 && && b.arvo==1 a.arvo=a.arvo+1; //a.arvo==2 && && b.arvo==2 Voidaan myös viitata:ainoalaskuri.arvo class VakioLaskuri final int arvo; VakioLaskuri() arvo=0; public void tik() arvo=arvo+1; 12

Luokkavakio Ainoa:static class Numero public static final int YKSI=1; Tähän vakioon viitataan: Numero.YKSI HUOM! public, protected ja private ovat toistensa poissulkevia. class Paaohjelma // public static void main (String[] args) System.out.prinln ( Hyvästi Julma Maailma! ); Viitataan:Paaohjelma.main (parametrit) Luokkametodi static metodi on ns. luokkametodi : => kaikki saman luokan oliot jakavat metodin keskenään Vinkkejä => luokkametodi voi olla myös eräänlainen alustaja => luokkametodia ei voi sitoa johonkin tiettyyn olioon 13

Luokan tehtäviä 1. Sitominen: luokka sitoo vain yhden käsitteen Koostesuhde 2. Kapselointi: käsitteen attribuutteja manipuloidaan metodien avulla 3. Abstrahointi: käyttäjän ei tarvitse tietää toteutusmekanismia 4. Jäsennys: luokka ilmaisee kuinka käsite liittyy toisiin käsitteisiin (luokkiin) Hyvän luokan tunnuspiirteitä Eli mikä? 1. Selkeys: luokka sitoo vain yhden käsitteen; attribuutit ja metodit ovat selviä ja tarkoituksenmukaisia 2. Riippumattomuus: luokan toetutusta voidaan muuttaa käyttäjistä riippumatta; onnistuu vain jos attribuutit ovat yksityisiä 3. Lyhyys: luokan määrittely selviää yhdellä silmäyksellä ( mitenkäs Javan oma luokkakirjasto? ;) 4. Mutatoitumattomuus: luokka kapseloi staattisen käsitteen; dynaamisuus saadaan metodien palautteessa metodi==funktio luokassa vain alustajia ja havainnoijia Aggregaatiolla kuvataan tapausta, jossa luokka koostuu toisista luokista tai sisältää toisia luokkia selvästi osinaan. (http://www.helsinki.fi/~ajrantan/uml.htm, helmikuu 2002) Kouluesimerkki: autossa on neljä pyörää auto pyörä pyörä pyörä pyörä 14

Perustapaus Perustapaus class Nimi private String nimi; class Nimi private String nimi; public Nimi (String nimi) this.nimi=nimi; public String kuka() return nimi; public Nimi (String nimi) this.nimi=nimi; public String kuka() return nimi; String private nimi Nimi nimi : String +Nimi (String nimi) +Nimi +String(nimi:String) kuka() +kuka() : String class Nimi private String nimi; Perustapaus Rajoitettu tapaus class Henkilo private String[] tunnus[]; tunnus; public Nimi (String nimi) this.nimi=nimi; public String kuka() return nimi; Nimi String nimi +Nimi (String nimi) +String kuka() public Henkilo () tunnus=new String[5]; public String tunnus(int i) return tunnus[i]; public void asetatunnus (int i, String t) tunnus[i]=t; 15

class Henkilo private String tunnus[]; public Henkilo () tunnus=new String[5]; public String tunnus(int i) return tunnus[i]; Rajoitettu tapaus public void asetatunnus (int i, String t) tunnus[i]=t; Henkilo String[5] tunnus +Henkilo() +String tunnus(int i) +void asetatunnus (int i, String t) Rajoittamaton tapaus class Henkilo protected Vector tunnus; public Henkilo () tunnus=new Vector(); public int tunnuksia() return tunnus.size(); public void lisaatunnus (String t) tunnus.add (t); class Henkilo private String tunnus[]; public Henkilo () tunnus=new String[5]; public String tunnus(int i) return tunnus[i]; Rajoitettu tapaus public void asetatunnus (int i, String t) tunnus[i]=t; private 0..5 Henkilo String tunnus +Henkilo() +String tunnus(int i) +void asetatunnus (int i, String t) class Henkilo protected Vector tunnus; public Henkilo () tunnus=new Vector(); public int tunnuksia() return tunnus.size(); Rajoittamaton tapaus public void lisaatunnus (String t) tunnus.add (t); Henkilo #Vector tunnus +Henkilo() +int tunnuksia() +void lisaatunnus (String t) 16

class Henkilo protected Vector tunnus; public Henkilo () tunnus=new Vector(); public int tunnuksia() return tunnus.size(); Rajoittamaton tapaus public void lisaatunnus (String t) tunnus.add (t); protected 0..* String Henkilo tunnus +Henkilo() +int tunnuksia() +void lisaatunnus (String t) Määrittelystä Vektori (Vector) on määräämättömän kokoinen taulukko, joka kasvaa tarpeen mukaan. Vector luokka kuuluu java.util pakettiin: import java.util.*; vektoriolio määritellään: Vector v; Vector Alustuksesta Useita eri alustusvaihtoehtoja: Vector() Constructs an empty vector so that its internal data array has size 10 and its standard capacity increment is zero. Vector(Collection c) Constructs a vector containing the elements of the specified collection, in the order they are returned by the collection's iterator. Vector(int initialcapacity) Constructs an empty vector with the specified initial capacity and with its capacity increment equal to zero. Vector(int initialcapacity, int capacityincrement) Constructs an empty vector with the specified initial capacity and capacity increment. Esim. vektorin(vector v) alustus: v=new Vector(); 17

Peruskäytöstä boolean add(object o) // boolean!?!? Appends the specified element to the end of this Vector. int size() Returns the number of components in this vector. Object elementat(int index) Returns the component at the specified index. void setelementat(object obj, int index) Sets the component at the specified index of this vector to be the specified object. boolean contains(object elem) Tests if the specified object is a component in this vector. Sekakokelmista Vektoriin talletetaanobject olioita, mikä mahdollistaa sekakokoelmien luonnin, ts. samassa vektorissa voi olla monentyyppisiä olioita. Esim. kokonaisluku ja merkkijono oliot: Integer i=new Integer(100); String s=new String( Heippa ); Nämä voidaan tallettaa samaan vektoriin: Vector v; v=new Vector(); v.add (i); v.add (s); Peruskäytöstä Sekakokoelmista Vector v; int i; v=new Vector(); v.add( Hello ); //palautteen saa v.add( World ); //unohtaa!? System.out.println (v.size()); //2 for (i=0; i<v.size(); i++) System.out.println (v.elementat(i)); Kuinka sekakokoelmaa sitten käytetään, jos tyyppiä ei tunneta etukäteen? Vector v; Object o; int i; o=v.elementat(5); if (o instanceof Integer) i=((integer)o).intvalue(); 18

Hashtable Motivointi Hashtable englanniksi; System.out.println (englanniksi.get( talo )); Motivointi String[] suomi; String[] englanti; int i, j, sanoja; for (i=0; i<sanoja; i++) if (suomi[i].equals( talo )) j=i; System.out.println (englanti[j]); Vaikeuksia: haku, lisäys, poisto, skaalautuvuus, Määrittelystä Assosiatiiviseen taulukkoon (Hashtable) talletetaan oliopareja: (avainolio,dataolio) avainolio yksilöi olioparin taulukossa dataolio sisältää varsinaisen haettavan informaation esim. suomi engalnti sanakirja Assosiatiivinen taulukkoh määritellään: Hashtable h; 19

Alustuksesta Peruskäytöstä Monta eri alustusvaihtoehtoa: Hashtable() Constructs a new, empty hashtable with a default capacity and load factor, which is 0.75. Hashtable(int initialcapacity) Constructs a new, empty hashtable with the specified initial capacity and default load factor, which is 0.75. Hashtable(int initialcapacity, float loadfactor) Constructs a new, empty hashtable with the specified initial capacity and the specified load factor. Hashtable(Map t) Constructs a new hashtable with the same mappings as the given Map. Esim: h=new Hashtable(); Hashtable englanniksi; englanniksi=new Hashtable(); englanniksi.put( talo, house );// palautteen saa englanniksi.put( kissa, cat ); // unohtaa!? System.out.println (englanniksi.size()); //2 System.out.println (englanniksi.get( talo )); englanniksi.put( talo, a house ); System.out.println (englanniksi.get( talo )); Peruskäytöstä Object put(object key, Object value) //ret:object?! Maps the specified key to the specified value in this hashtable. Object get(object key) Returns the value to which the specified key is mapped in this hashtable. Boolean containskey(object key) Tests if the specified object is a key in this hashtable. Object remove(object key) //ret:object?! Removes the key (and its corresponding value) from this hashtable. Iteraattori 20

Määrittelystä Iteraattori on tarkoitettu kokoelman alkioiden läpikäyntiin (haku, lisäys, poisto). Javassa iteraattoreita on kahta päätyyppiä: perusiteraattori (Iterator) on yksisuuntainen listaiteraattori (ListIterator) on kaksisuuntainen Iteraattorit kuuluvat java.util pakettiin: import java.util.*; Esim. iteraattori määritellään: Iterator i; Peruskäytöstä boolean hasnext() Returns true if the iteration has more elements. Object next() Returns the next element in the interation. i=h.values().iterator(); while (i.hasnext()) System.out.println (i.next()); Iterator:lla on myös muita rutiineita Alustuksesta Iteraattoria ei varsinaiseti alusteta, vaan sitä pyydetään kokoelmalta. Hashtable h; Iterator i; i=h.values().iterator(); Iteraattorin eduista 1. Iteraattori on abstrakti käsite jonkin kokoelman läpikäymiseen => intention selkeys 2. Iteraattori on täysin riippumaton kokoelman rakenneominaisuuksista => uudelleenkäytettävyys 3. Iteraattorin käyttö ei edellytä tarkkaa etukäteisjärjestystä, eikä edes numeroituvuutta (!) => yleissoveltuvuus 4. Iteraattorin käyttö edellyttää kylläkin seuraavuus käsitettä kokoelmalta 21

Tiedostot Lukijat Syöttövirrat Tulostusvirrat 22

Kirjoittajat Käyttö: tiedosto import java.io.*; class Olioni implements Serializable private String s; public Olioni (String s) this.s=s; public String tostring() return "OLIONI:"+s; Käyttö: pääte import java.io.*; class T5 public static void main (String[] a) try String s; BufferedReader br; InputStreamReader isr; isr=new InputStreamReader(System.in); br=new BufferedReader(isr); System.out.println ("Kirjoita jotain ja paina ENTER!"); s=br.readline(); System.out.println ("Kirjoitit: "+s); catch (IOException e) System.out.println ("VIRHE!"); Käyttö: tiedosto import java.io.*; class Olioni implements Serializable private Kirjoitus String tiedostoon: s; import java.io.*; public import Olioni java.util.*; (String s) this.s=s; Vector v=new Vector(); public v.addelement String tostring() (new Olioni("kissa")); return v.addelement "OLIONI:"+s;(new Olioni("koira")); try FileOutputStream fos = new FileOutputStream("oliot.jbs"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeobject (v); oos.close(); fos.close(); catch (IOException ioe) 23

Käyttö: tiedosto import java.io.*; class Olioni implements Serializable private Kirjoitus String tiedostoon: s; import java.io.*; Tiedostosta public import Olioni lukeminen: java.util.*; (String import s) this.s=s; java.io.*; import Vector java.util.*; v=new Vector(); public v.addelement String tostring() (new Olioni("kissa")); return try v.addelement try "OLIONI:"+s; (new Olioni("koira")); FileInputStream fis fis = new new FileInputStream("oliot.jbs"); ObjectInputStream try ois ois = new new ObjectInputStream(fis); Vector FileOutputStream d=(vector)ois.readobject(); ois.close(); fos = new FileOutputStream("oliot.jbs"); ObjectOutputStream fis.close(); oos = new ObjectOutputStream(fos); oos.writeobject (v); catch oos.close(); catch (IOException (ioe) (ioe) fos.close(); catch catch catch (ClassNotFoundException (IOException cfe) ioe) cfe) Sanoma Perinnässä kaikki piirteet välittyvät perijälle suojaukset voivat kuitenkin estää niiden käytön. Perintää on käytetty oikein, kun voi lukea: "luokka A on eräänlainen luokka B" Perintä class classelain private int intpaino; public Elain Elain (int (intpaino) this.paino=paino; public int intpaino() return paino; Esimerkki class classkissa Kissaextends Elain Elain public Kissa Kissa (int (intpaino) super(paino); public String aani() return "Miau"; 24

class classelain private int intpaino; UML merkintä 1. Poikkeushierarkia Throwable public Elain Elain (int (intpaino) this.paino=paino; public int intpaino() return paino; class classkissa Kissaextends Elain Elain public Kissa Kissa (int (intpaino) super(paino); public String aani() return "Miau"; Elain Kissa Error AWTError, Exception RunTimeException IOException, ArithmeticException, Poikkeukset ja perintä Omien poikkeusten luomisesta 1/2 Entä jos halutaan nostaarumaexception poikkeus, jota Javassa ei ole (varmastikaan, ainakaan vielä) määritelty? Luodaan uusi aliluokka: class RumaException extends Exception Nyt voidaan nostaa ruma poikkeus: throw new RumaException(); 25

Omien poikkeusten luomisesta 2/2 Kuinkas määritelläänjuoksevaexception poikkeus, joka on RuntimeException tyyppinen? Suojausmääreet; osa II Luodaan uusiruntimeexception aliluokka: class JuoksevaException extends RuntimeException Nyt voidaan nostaa joukseva poikkeus: throw new JuoksevaException(); Viesti poikkeuksesa Julkinen:public class JuoksevaException extends RuntimeException public JuoksevaException (String viesti) super (viesti); Nyt voidaan nostaa joukseva poikkeus: throw new JuoksevaException( maratoni ); Ja viesti saaadaan: try catch (JuoksevaException ejuokseva) System.out.println (ejuokseva.getmessage()); julkinen metodi ja attribuutti näkyvät kaikille, myös perilliselle poikkeus: alustajaa ei varsinaisesti peritä => kullekin luokalle pitää kirjoittaa oma alustaja perityn alustajan nimi muuttuu super:ksi perinnässä 26

Julkinen:public Paketoitu: (ei avainsanaa) class classhenkilo //MUTATOITUMATON private String nimi; nimi; public Henkilo (String nimi) nimi) this.nimi=nimi; public String kuka() return nimi; nimi; class classmies Miesextends Henkilo public double rahaa; public Mies Mies (String nimi) nimi) super(nimi); public String kuka() return nimi; package Yritys; class classhenkilo //MUTATOITUMATON private String nimi; nimi; public Henkilo (String nimi) nimi) this.nimi=nimi; String kuka() return nimi; nimi; package Yritys; class classmies Miesextends Henkilo public double rahaa; public Mies Mies (String nimi) nimi) super(nimi); String kuka() return nimi; Paketoitu: (ei avainsanaa) Paketoitu: (ei avainsanaa) paketoitu metodi ja attribuutti näkyvät kaikille saman paketin luokille, siis myös perilliselle, jos perijä on samassa paketissa paketoitu metodi tai attribuutti eivät näy perilliselle, joka on toisessa paketissa package Yritys; class classhenkilo //MUTATOITUMATON private String nimi; nimi; public Henkilo (String nimi) nimi) this.nimi=nimi; String kuka() return nimi; nimi; package package Yritys; KilpailevaYritys; class classmies Miesextends Henkilo public double rahaa; public Mies Mies (String nimi) nimi) super(nimi); String kuka() return nimi; 27

Periytyvä:protected Yksityinen:private Perityvä metodi ja attribuutti näkyvät perijälle, paketista riippumatta! Yksityinen metodi ja attribuutti eivät koskaan näy muille luokiell, ei edes perilliselle! Periytyvä:protected Yksityinen:private package Yritys; class classhenkilo //MUTATOITUMATON private String nimi; nimi; public Henkilo (String nimi) nimi) //ALKUEHTO: nimi!=null this.nimi=nimi; protected String kuka() return nimi; nimi; package KilpailevaYritys; class classmies Miesextends Henkilo public double rahaa; public Mies Mies (String nimi) nimi) //ALKUEHTO: nimi!=null super(nimi); protected String kuka() return nimi; class classhenkilo //MUTATOITUMATON private String nimi; nimi; public Henkilo (String nimi) nimi) //ALKUEHTO: nimi!=null this.nimi=nimi; private String kuka() return nimi; nimi; class classmies Miesextends Henkilo public double rahaa; public Mies Mies (String nimi) nimi) //ALKUEHTO: nimi!=null super(nimi); private String kuka() return nimi; 28

Polymorfismi Korvaus Henkilo Mies Polymorfismista Oletetaan seuraavat luokat määritellyiksi: Lisäksi on määritelty seuraavat oliot: Henkilo h; Mies m; Tällöin ainakin seuraavat alustukset ovat mahdollisia: h=new Henkilo(); m=new Mies(); Myös seuraava alustus on mahdollinen: h=new Mies(); UML kaavio havainnolistaa syyn tähän ns. polymorfismiin. Perustapauksesta class classkuvio class classympyra extends Kuvio Kuvio public double pintaala() return 0; 0; private double sade; sade; public double pintaala() return 3.1415*sade*sade; class classnelio Nelioextends Kuvio Kuvio private double sivu; sivu; public double pintaala() return sivu*sivu; Korvaavien metodien palautustyyppien ja parametrien tulee olla samat! 29

Attribuuteista Perustapaus Attribuutteja ei voi korvata! class classa public int inti; i; public A() A() i=3; i=3; class classb extends A public double i; i; public B() B() i=3.1415 A a; a=new B(); System.out.println(a.i); // ==> 3 B b; b=new B(); System.out.println(b.i); // ==> 3.1415 class classkuvio public double pintaala() return 0; 0; Kuvio k; k=new Kuvio(); System.out.println(k.pintaAla()); // ==> 0 Dynaaminen sidonta class classkuvio public double pintaala() return 0; 0; Korvaus Kuvio k; k=new Kuvio(); System.out.println(k.pintaAla()); // ==> 0 class classympyra extends Kuvio Kuvio private double sade; sade; public Ympyra (double sade) sade) this.sade=sade; public double pintaala() return 3.1415*sade*sade; Ympyra y; y=new Ympyra(2.0); System.out.println(y.pintaAla()); // ==> 12.566 30

Dynaaminen sidonta class classkuvio public double pintaala() return 0; 0; Kuvio k; k=new Kuvio(); System.out.println(k.pintaAla()); // ==> 0 Virheellinen perintä class classympyra extends Kuvio Kuvio private double sade; sade; public Ympyra (double sade) sade) this.sade=sade; public double pintaala() return 3.1415*sade*sade; Kuvio k; k=new Ympyra(2.0); System.out.println(k.pintaAla()); // ==> 4 Virheellinen koodi Virheellisen perinnän tunnuspiirteitä class classkuvio public double pintaala() return 0; 0; class classympyra extends Kuvio Kuvio private double sade; sade; public Ympyra (double sade) sade) this.sade=sade; public double pintaala() return 3.1415*sade*sade; Kuvio k; k=new Kuvio(); System.out.println(k.pintaAla()); // ==> 0 Ympyra y; y=new Kuvio(); System.out.println(y.pintaAla()); perintää ei voi lukea muodossa "luokka A on eräänlainen luokka B" metodit joutuvat käsittelemään Object luokan olioita perinnän myötä luokkaan tulee tarpeettomia metodeja perillisen metodit joutuvat kilpailemaan yläluokan metodien kanssa, jolloin ohjelmoijalle jää epäselväksi, kummanko luokan metodia tulisi käyttää 31

Esimerkki: kokonaislukupino Kuoriluokka private Stack Kokonaislukupino +Kokonaislukupino() +boolean tyhja() +int ota() +void lisaa(int i) Kuoriluokan tehtävä kuoriluokan tehtävä on luoda rajapinta kahden luokan välille käytetään, kun kuorrutettavassa luokassa on tarpeettomia metodeja käytetään, kun metodien parametrien tyypit ovat liian epätarkkoja, esim. Object tyyppisiä käytetään, kun metodien nimet ovat harhaanjohtavia Esimerkki: kokonaislukupino import java.util.*; class Kokonaislukupino private Stack pino; public Kokonaislukupino() pino=new Stack(); public boolean tyhja() return pino.empty(); public int ota() return ((Integer)pino.pop()).intValue(); public void lisaa (int i) pino.push(new Integer(i)); 32

Abstrakti luokka Peruskäytöstä Abstraktia luokkaa käytetään kapseloimaan jonkin toiminnon yleiset piirteet. Yksityiskohdat jätetään perijän huoleksi. Elain abstract +Elain() +String aani() abstract +void aantele() abstract class Elain public abstract String aani(); public void aantele() System.out.println(aani()); Kissa Koira +Kissa() +Koira() +String aani() miau hau class Kissa Koira extends Elain public String aani() return miau ; hau ; Koira Kissa o=new k=new Koira(); Kissa(); o.aantele(); k.aantele(); Merkinnästä Javassa ja UML:ssä Elain abstract +Elain() +String aani() abstact +void aantele() abstract class Elain public abstract String aani(); public void aantele() System.out.println(aani()); Rajapintaluokka HUOM!Elain()on vakioalustaja, jonka Java tuottaa automaattisesti! 33

Merkinnästä Javassa ja UML:ssä Peruskäytöstä <<interface>> Yhteystieto +String nimi() +String osoite() interface Yhteystieto public String nimi(); public String osoite(); Rajapintaluokkaa käytetään kapseloimaan jonkin toiminnon kutsujen piirteet. Yksityiskohdat jätetään rajapinnan toteuttajan huoleksi. <<interface>> Yhteystieto +String nimi() +String osoite() interface Yhteystieto public String nimi(); public String osoite(); HUOM! Rajapintaluokalla ei ole alustajaa, koska rajapintaluokka on aina abstrakti osa toista luokkaa! Kaarlo +Kaarlo() +String nimi() +String osoite() class Kaarlo implements Yhteystieto public Kaarlo() public String nimi() return Kaarlo H. Enkilo ; public String osoite() return Kaarlontie 1 ; Merkinnästä Javassa ja UML:ssä Peruskäytöstä Rajapinnnan käyttöön liittyy usein myös jokin protokolla, kutsujärjestys, jota mallinnetaan esim. tilakaaviolla: <<interface>> Runnable +void start() +void run() +void sleep(ms:long) Ajetaan sleep() run() ei ajeta start() HUOM! Runnable rajapintaan kuuluu myös muita metodeja; kuitenkinstop(),suspend(),resume() eivät ole enää suositeltuja! interface interfaceyhteystieto public public String String nimi(); nimi(); public public String String osoite(); osoite(); class classkaarlo Kaarloimplements Yhteystieto public publickaarlo() public publicstring Stringnimi() nimi() return return Kaarlo Kaarlo H. H. Enkilo ; Enkilo ; public publicstring Stringosoite() return return Kaarlontie 1 ; 1 ; void tulosta (Yhteystieto y) System.out.println(y.nimi()); System.out.println(y.osoite()); Kaarlo kaarlo; kaarlo=new Kaarlo(); tulosta (kaarlo); 34

Useat rajapinnat Luokka voi samaan aikaan toteuttaa useita eri rajapintoja: class Kaarlo implements Yhteystieto, Runnable, public Kaarlo() public String nimi() return Kaarlo H. Enkilo ; public String osoite() return Kaarlontie 1 ; public void start() import javax.swing.*; Esimerkki: JFrame class JF public static void main (String[] argumentit) JFrame jf=new JFrame("Hello Worms!"); jf.setvisible(true); hävittää ikkunan, muttei lopeta ohjelmaa Swing: ikkunat Ikkunan sulkeminen lopettaa myös ohjelman import javax.swing.*; class JF public static void main (String[] argumentit) JFrame jf=new JFrame("Hello Worms!"); jf.setdefaultcloseoperation(jframe.exit_on_close); jf.setvisible(true); 35

Ikkunan ominaisuuksia Sallitaanko ikkunan koon muutos? setresizable() Ikkunan piilotus: hide() taisetvisible(false) Otsikon vaihtaminen: settitle ("otsikko") Ikkuna ja ajoluokka OmaIkkuna.java: import javax.swing.*; class OmaIkkuna extends JFrame public OmaIkkuna() super("hello Worms!"); setdefaultcloseoperation(jframe.exit_on_close); getcontentpane().add(new JLabel("Worms say Hi!")); pack(); setvisible(true); Ajo.java: class Ajo public static void main (String[] argumentit) new OmaIkkuna(); Oma ikkunaluokka Swingissä ideana on luoda oma ikkunaluokka perimällä se JFrame luokasta.jframe luokkaa käytetään harvoin sellaisenaan. Swing: nimiöt Tällöinmain() metodi sijoitetaan ko. ikkunaluokkaan tai luoda erillinen ajoluokka, joka luo omasta ikkunaluokasta ikkunan. Näistä jälkimmäinen tapa on suositeltavampi. 36

Nimiö: JLabel Määrittely: JLabel j; Swing: asemointi Alustus: j=new JLabel("Teksti tähän"); Sisällön muuttaminen myöhemmin: j.settext ("Uusi teksti tähän"); Nimiön lisääminen ikkunalle Taulu: JPanel import javax.swing.*; class JF public static void main (String[] argumentit) JFrame jf=new JFrame("Hello Worms!"); jf.setdefaultcloseoperation(jframe.exit_on_close); jf.getcontentpane().add(new JLabel("Worms say Hi!")); jf.setvisible(true); hmm.. ikkuna puristetaan sisällön muotoiseksi komennolla: jf.pack() JPanel on taulu, johon voidaan määrätä asemointitekniikka voidaan sijoittaa komponentteja voidaan sijoittaa myös muita tauluja komponentteina 37

import javax.swing.*; Esimerkki: JPanel class OmaIkkuna extends JFrame public OmaIkkuna () super("hello Worms!"); setdefaultcloseoperation(jframe.exit_on_close); JPanel p=new JPanel(); p.add(new JLabel("Worms say Hi!")); getcontentpane().add(p); pack(); setvisible(true); Esimerkki: FlowLayout import javax.swing.*; import java.awt.*; class OmaIkkuna extends JFrame public OmaIkkuna () super("hello Worms!"); setdefaultcloseoperation(jframe.exit_on_close); JPanel p=new JPanel(new FlowLayout()); p.add(new JLabel("1")); p.add(new JLabel("2")); p.add(new JLabel("3")); getcontentpane().add(p); pack(); setvisible(true); Asemointi: FlowLayout Asemointi: GridLayout Java tarjoaa useita eri asemointitekniikoita (Layout), joita voidaan tarvittaessa yhdistellä.flowlayout:ssa komponentit sijoitetaan vasemmalta oikealle lisäysjärjestyksessä. GridLayout:ssa komponentit sijoitetaan vasemmalta oikealle ja ylhäältä alas lisäysjärjestyksessä. Tällä asemointitekniikalla määrätään aluksi hilan koko. FlowLayout Object Object Object GridLayout (3,3) Object Object Object Object Object Object Object Object Object 38

Esimerkki: GridLayout import javax.swing.*; import java.awt.*; class OmaIkkuna extends JFrame public OmaIkkuna () super("hello Worms!"); setdefaultcloseoperation(jframe.exit_on_close); JPanel p=new JPanel(new GridLayout(2,3)); p.add(new JLabel("1")); p.add(new JLabel("2")); p.add(new JLabel("3")); p.add(new JLabel("4")); p.add(new JLabel("5")); p.add(new JLabel("6")); getcontentpane().add(p); pack(); setvisible(true); Esimerkki: BorderLayout import javax.swing.*; import java.awt.*; class OmaIkkuna extends JFrame public OmaIkkuna () super("hello Worms!"); setdefaultcloseoperation(jframe.exit_on_close); JPanel p=new JPanel(new BorderLayout()); p.add(new JLabel("1", JLabel.CENTER), BorderLayout.CENTER); p.add(new JLabel("2", JLabel.CENTER), BorderLayout.WEST); p.add(new JLabel("3", JLabel.CENTER), BorderLayout.EAST); p.add(new JLabel("4", JLabel.CENTER), BorderLayout.NORTH); p.add(new JLabel("5", JLabel.CENTER), BorderLayout.SOUTH); getcontentpane().add(p); pack(); setvisible(true); Asemointi: BorderLayout Oma taululuokka BorderLayout:ssa komponentit sijoitetaan ilmansuunnittain. Swingissä ideana on luoda oma taululuokka perimällä se JPanel luokasta. BorderLayout West North Center East Tällöin omassa taululuokassa voidaan suorittaa komponenttien asemointi paikallisesti ja samoja tauluja voidaan helposti "monistaa" samaan tai eri ikkunaan. South 39

Oma taululuokka ja sen käyttö OmaTaulu.java: import javax.swing.*; import java.awt.*; class class OmaTaulu extends JPanel public OmaTaulu() super(new BorderLayout()); add(new JLabel("Keski", JLabel.CENTER), BorderLayout.CENTER); add(new JLabel("Pohjola", JLabel.CENTER), BorderLayout.NORTH); OmaIkkuna.java: import javax.swing.*; class class OmaIkkuna extends JFrame public OmaIkkuna() super("hello Worms!"); setdefaultcloseoperation(jframe.exit_on_close); getcontentpane().add(new OmaTaulu()); pack(); setvisible(true); Kenttä: JTextField Määrittely: JTextField t; Alustus: tai t=new JtextField("Oletusteksti tähän"); t=new JtextField("Oletusteksti tähän",20); Sisällön tiedustelu: tai String s=t.gettext(); String s=t.getselectedtext(); Sisällön muuttaminen myöhemmin: t.settext ("Uusi teksti tähän"); Muutoksen estäminen: t.seteditable (false); Swing: kentät Kentän lisääminen ikkunalle import javax.swing.*; class OmaIkkuna extends JFrame private JTextField kentta; public OmaIkkuna () super("ikkuna"); setdefaultcloseoperation(jframe.exit_on_close); kentta=new JTextField("(oletusteksti)"); getcontentpane().add(kentta); pack(); setvisible(true); 40

Oma kokonaislukukenttä Entäpä jos tarvittaisiinkin koknaislukukenttä, johon käyttäjä saa kirjoittaa vain kokonaislukuja? Yksi keino on luoda uusi kenttäluokka, joka perii JTextField:in ja laajentaa sitä kahdella uudella metodilla setint(int i) ja int getint () throws NumberFormatException. Kokonaislukukentän lisääminen ikkunalle import javax.swing.*; class OmaIkkuna extends JFrame private IntKentta kentta; public OmaIkkuna () super("ikkuna"); setdefaultcloseoperation(jframe.exit_on_close); kentta=new IntKentta( 123); getcontentpane().add(kentta); pack(); setvisible(true); Oma kokonaislukukenttä tarkemmin import javax.swing.*; import java.awt.*; class IntKentta extends JTextField public IntKentta (int value) super(string.valueof(value)); public void setint (int value) settext (String.valueOf(value)); public int getint () throws NumberFormatException return Integer.valueOf(getText()).intValue(); Iso kenttä: JTextArea Määrittely: JTextArea t; Alustus: tai t=new JtextArea("Oletusteksti tähän"); t=new JtextArea("Oletusteksti",20,60); Sisällön tiedustelu: tai String s=t.gettext(); String s=t.getselectedtext(); Sisällön muuttaminen myöhemmin: t.settext ("Uusi teksti tähän"); Muutoksen estäminen: t.seteditable (false); 41

kentän lisääminen ikkunalle import javax.swing.*; class OmaIkkuna extends JFrame private JTextArea kentta; public OmaIkkuna () super("ikkuna"); setdefaultcloseoperation(jframe.exit_on_close); kentta=new JTextArea("(oletusteksti)",5,20); getcontentpane().add(kentta); pack(); setvisible(true); Painike: JButton JButton on painike johon voidaan sijoittaa teksti, kuva, jne. jotka lähettää viestin painalluksesta jonka lähettämä viesti voidaan käsitellä toisessa oliossa Swing: painikkeet import javax.swing.*; Painike: JButton class OmaIkkuna extends JFrame public OmaIkkuna () super("hello Worms!"); setdefaultcloseoperation(jframe.exit_on_close); getcontentpane().add(new JButton("Klikkaas mua")); pack(); setvisible(true); 42

Viestit ja kuuntelijat Painikkeet taulussa Javassa näyttökomponentit lähettävät viestejä (AWTEvent). Viestit välitetään rekisteröityneille kuuntelijoille (EventListener). Viestin kuuntelijaolio rekisteröi itsensä sille komponentille, jonka viestejä se haluaa kuunnella. Esimerkiksi painikkeen kuuntelijan on rekisteröidyttävä sille painikkeelle, jota se haluaa kuunnella. Usein on tarve luoda taulu, jossa on nimiöitä, tekstikenttiä ja painikkeita. Tällaisessa taulussa osa painikkeista ja niiden lähettämistä viesteistä tulisi ohjata taulun omistajalle (ikkunalle). Kuinkas se sitten tapahtuu? Tapoja on monia. Ehkä selkein ratkaisu olisi luoda oma rajapinta kuuntelijalle. On kuitenkin helpompaa käyttää Swingin viestejä sellaisenaan: Ideana on, että taulussa määritellään metodit, joilla voidaan kysyä, mikä painike aiheutti viestin. Taulun luonnin yhteydessä lisätään taulun painikkeille kuuntelija, joka toteuttaa ActionListener rajapinnan. Painikeviestin sieppaus import javax.swing.*; import java.awt.*; import java.awt.event.*; class OmaIkkuna extends JFrame implements ActionListener private JLabel nimio; private JButton painike; public void actionperformed (ActionEvent e) nimio.settext(nimio.gettext()+"."); public OmaIkkuna () super("ikkuna"); setdefaultcloseoperation(jframe.exit_on_close); nimio=new JLabel("Painettu: "); painike=new JButton("Klikkaas!"); painike.addactionlistener(this); getcontentpane().setlayout (new GridLayout(2,1)); getcontentpane().add(painike); getcontentpane().add(nimio); pack(); setvisible(true); Oma taulu import javax.swing.*; import java.awt.*; import java.awt.event.*; class OmaTaulu extends JPanel private JButton painikea; private JButton painikeb; public OmaTaulu (ActionListener kuuntelija) super(); setlayout (new GridLayout(1,2)); painikea=new JButton(" A "); painikea.addactionlistener(kuuntelija); add(painikea); painikeb=new JButton(" B "); painikeb.addactionlistener(kuuntelija); add(painikeb); public boolean apainettu (ActionEvent e) return e.getsource()==painikea; public boolean bpainettu (ActionEvent e) return e.getsource()==painikeb; 43

Oman taulun kuutelija import javax.swing.*; import java.awt.*; import java.awt.event.*; class OmaIkkuna extends JFrame implements ActionListener private OmaTaulu taulu; public void actionperformed (ActionEvent e) if (taulu.apainettu(e)) System.out.println("A"); if (taulu.bpainettu(e)) System.out.println("B"); Valikkojen käytöstä Yksi valikko tulisi kapseloida omaan luokkaansa, jonka luonnin yhteydessä rekisteröidään valikon kuuntelija. Tekniikka on siis sama kuin painiketaululla. public OmaIkkuna () super("ikkuna"); setdefaultcloseoperation(jframe.exit_on_close); taulu=new OmaTaulu(this); getcontentpane().add(taulu); pack(); setvisible(true); Oma valikko Swing: valikot import javax.swing.*; import java.awt.event.*; class TiedostoValikko extends JMenu private JMenuItem lue; private JMenuItem talleta; public TiedostoValikko (ActionListener kuuntelija) super("tiedosto"); lue=new JMenuItem("lue"); lue.addactionlistener(kuuntelija); add(lue); talleta=new JMenuItem("talleta"); talleta.addactionlistener(kuuntelija); add(talleta); public boolean luevalittu(actionevent e) return e.getsource()==lue; public boolean talletavalittu(actionevent e) return e.getsource()==talleta; 44

Oman valikon käyttö Viestidialogi import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Ikkuna extends JFrame implements ActionListener private TiedostoValikko tiedostovalikko; public Ikkuna() super(otsikko); setdefaultcloseoperation(jframe.exit_on_close); tiedostovalikko=new TiedostoValikko(this); JMenuBar valikko=new JMenuBar(); valikko.add(tiedostovalikko); setjmenubar(valikko); pack(); setvisible(true); JOptionPane.showMessageDialog( ikkunaolio, "VIESTI", "OTSIKKO", JOptionPane.PLAIN_MESSAGE ); public void actionperformed (ActionEvent e) if (tiedostovalikko.luevalittu(e)) System.out.println ("LUE"); if (tiedostovalikko.talletavalittu(e)) System.out.println("TALLETA"); Listausdialogi Swing: dialogeja JTextArea t=new JTextArea(a.toString()); t.seteditable(false); JOptionPane.showMessageDialog( ikkunaolio, t, "OTSIKKO", JOptionPane.PLAIN_MESSAGE ); 45

Vahvistusdialogi Tiedoston talletusdialogi JOptionPane.showConfirmDialog( ikkunaolio, "Oletko varma?", "OTSIKKO", JOptionPane.YES_NO_OPTION ); JFileChooser tiedostot; if (tiedostot.showsavedialog(ikkunaolio) ==JFileChooser.APPROVE_OPTION) System.out.println( tiedostot.getselectedfile().getpath() ); palauttaajoptionpane.yes_option:nin, jos käyttäjä painaa dialogin Yes painiketta. Tiedoston lukudialogi JFileChooser tiedostot; if (tiedostot.showopendialog(ikkunaolio) ==JFileChooser.APPROVE_OPTION) System.out.println( tiedostot.getselectedfile().getpath() ); MVC arkkitehtuuri 46

Motivointi Tee Javalla ohjelma, joka pitää kirjaa kahdesta henkilöstä, heidän nimestä ja osoitteesta. Ohjelman pitäisi olla helposti ylläpidettävä, sillä henkilötietoja saatetaan tarvita myöhemmin lisää. Lomakepohjaisista ohjelmista tulee lähes poikkeuksetta MVC patternin mukaisia, jos halutaan ylläpidettävyyttä. MVC patternissa on: mallikomponentti (Model) Henkilo luokka Tee Javalla ohjelma, joka pitää kirjaa kahdesta henkilöstä, heidän nimestä ja osoitteesta. String nimi String osoite Henkilo +Henkilo (String nimi, String osoite) +String nimi() +String osoite() näkymäkomponentti (View) ohjauskomponentti (Control) Mallikomponentti Tee Javalla ohjelma, joka pitää kirjaa kahdesta henkilöstä, heidän nimestä ja osoitteesta. HenkiloArkisto luokka Tee Javalla ohjelma, joka pitää kirjaa kahdesta henkilöstä, heidän nimestä ja osoitteesta. private 1..2 Henkilo HenkiloArkisto Henkilo h1 Henkilo h2 HenkiloArkisto +HenkiloArkisto() +Henkilo henkilo(int i) PRE: 1<=i<=2 +void asetahenkilo (int i, Henkilo h) PRE: 1<=i<=2 47

Näkymäkomponentti HenkiloPainikkeet luokka: näkymäosa Yksinkertainen täyttölomake: Nimi: Osoite: henkilö1 henkilö2 päivitä HenkiloTaulu HenkiloPainikkeet JButton henkilo1 JButton henkilo2 JButton paivita JPanel HenkiloPainikkeet private private ArkistoIkkuna HenkiloTaulu luokka ArkistoIkkuna luokka: näkymäosa JPanel JFrame JTextField nimi JTextField osoite HenkiloTaulu +Henkilo annahenkilo() +void asetahenkilo (Henkilo h) +ArkistoIkkuna() ArkistoIkkuna HenkiloTaulu taulu HenkiloPainikkeet painikkeet 48

Ohjauskomponentti Yksinkertainen täyttölomake: Nimi: Osoite: henkilö1 henkilö2 päivitä ArkistoIkkuna luokka: ohjausosa <<interface>> HenkiloPainikkeet.Kuuntelija +void henkilo1() +void henkilo2() +void paivita() HenkiloArkisto private HenkiloPainikkeet private ArkistoIkkuna HenkiloArkisto arkisto void paivitanakyma() HenkiloIkkuna HenkiloPainikkeet luokka: ohjausosa Henkilo luokka <<interface>> ActionListener HenkiloPainikkeet +interface Kuuntelija +henkilo1() +henkilo2() +paivita() Kuuntelija kuuntelija +HenkiloPainikkeet (Kuuntelija k) +void actionperformed (ActionEvent e) String nimi String osoite Henkilo +Henkilo (String nimi, String osoite) +String nimi() +String osoite() 49

HenkiloArkisto luokka HenkiloPainikkeet luokka Henkilo h1 Henkilo h2 HenkiloArkisto +HenkiloArkisto() +Henkilo henkilo(int i) PRE: 1<=i<=2 +void asetahenkilo (int i, Henkilo h) PRE: 1<=i<=2 JPanel <<interface>> ActionListener HenkiloPainikkeet +interface Kuuntelija +henkilo1() +henkilo2() +paivita() Kuuntelija kuuntelija JButton henkilo1 JButton henkilo2 JButton paivita +HenkiloPainikkeet (Kuuntelija k) +void actionperformed (ActionEvent e) HenkiloTaulu luokka ArkistoIkkuna luokka JTextField nimi JTextField osoite JPanel HenkiloTaulu +Henkilo annahenkilo() +void asetahenkilo (Henkilo h) JFrame <<interface>> HenkiloPainikkeet.Kuuntelija ArkistoIkkuna HenkiloTaulu taulu HenkiloPainikkeet painikkeet HenkiloArkisto arkisto +ArkistoIkkuna() void paivitanakyma() +void henkilo1() +void henkilo2() +void paivita() 50

Pääluokka HenkiloArkistoOhjelma +void static main (String[] argumentit) 51