812341A Olio-ohjelmointi, 2016 Peruskäsitteet, jatkoa
Muuttujat, attribuuttien määrittely Olion attribuutit (jäsenmuuttujat) ovat olion muuttujia, ovat olemassa olion olemassaolon ajan Olion attribuutit säilyttävät arvonsa metodien kutsujen välilläkin Attribuutit kuvaavat olion rakenteen Attribuuttien arvot muodostava olion tilan Javalla 2
Muuttujat, attribuuttien määrittely Määrittely [näkyvyysmääre][static][final][transient] [volatile] tyyppi attribuutinnimi; Näkyvyysmääre määrittään sen missä attribuuttia voi käyttää ( näkyy ) Javalla 3
Muuttujat, attribuuttien määrittely Olion attribuutit määritellään yleensä private tai protected Tiedon suojaus Olio piilottaa sisäisen toteutuksen private rajaa attribuutin vain olion omaan käyttöön protected rajaa näkyvyyden olion jälkeläisiin (aliluokkiin) Näkyvyysrajoitus ei pidä aivan paikkaansa, mutta Javalla 4
Muuttujat, attribuuttien määrittely Attribuuteille määriteltävä saanti- ja asetusmetodit, joilla attribuutin arvoa voi kysellä ja asettaa static-määreellä attribuutti muuttuu luokkakohtaiseksi Yhteinen kaikille luokan olioille Sama arvo näkyy kaikille oliolle Jos joku olio muuttaa arvoa muutos näkyy heti muille saman luokan olioille Javalla 5
Muuttujat, attribuuttien määrittely Attribuutit määritellään luokan määrittelyn sisällä, mutta ei metodien määrittelyjen sisällä class Aika { private int tunnit, minuutit, sekunnit; } Edellä on määritelty luokka, josta tehdyn olion attribuutteihin ei pääse käsiksi, koska attribuutit on määritelty private tyyppisiksi! Javalla 6
Metodit Määrittely [näkyvyysmääre] [abstract] [static] [final] [synchronized][<tyyppiparametrit>] palautusarvontyyppi metodinnimi ([parametrit]) [throws PoikkeuksenTyyppi] { //metodin runko } Otsikko Tyyppi Nimi Parametrit, metodin lähtötiedot Runko Metodin varsinainen toteutus Javalla 7
Metodit Näkyvyysmääreet samat kuin attribuuteilla ja niiden vaikutus näkyvyyteen sama abstract avainsana määrittelee metodin Jolla ei ole runkoa (=totetus) Määrittely päättyy puolipisteeseen Metodin toteutus muualla final Metodi on ei-virtuaalinen, ei voi syrjäytää (=määritellä uudelleen) jälkeläisluokassa Jos metodin näkyvyysmääre on private, metodi automaattisesti myös ei virtuaalinen Javalla 8
Metodit static Luokkakohtainen metodi sychronized Liittyy säikeisiin Tyyppiparametrit liittyvät generisiin tyyppeihin (tästä lisää myöhemmin) Palautusarvon tyyppi ilmoittaa minkä tyyppisen arvon metodi palauttaa return-lauseella kutsujalleen (kuten C:ssä) void ilmoittaa, että metodi ei palauta mitään Javalla 9
Metodit Metodin parametrit Metodin muuttujia (käytössä vain metodin sisällä) Arvo kutsun yhteydessä Todelliset vs. muodolliset parametri Muodollisten parametien määrittely tyyppi paramnimi1, tyyppi paramnimi2, tyyppi paramnimin Muodollisen parametrin määrittelyssä voi käyttää final-avainsanaa, jolla estetään metodissa käytettävän muuttujan arvon muuttaminen Javalla 10
Metodit parametrilistan viimeinen parametri voi olla vaihtuvanmittainen parametri (lisää myöhemmin) Metodien nimirajoitukset samat kuin muillakin tunnuksilla Metodin nimi alkaa pienellä kirjaimella Olion attribuuttien arvoja käsittelevät metodit Nimetään get- ja set-alkuisiksi (saantimetodeja) Javalla 11
Metodit Metodin kutsuminen Lasketaan mahdollisten todellisten parametrien arvot Arvo voi olla muuttuja, lauseke tai vakioarvo Todellisten parametrien arvot kopioidaan muodollisten parametrien arvoiksi Metodin parametrit ja muuttujat luodaan metodia kutsuttaessa Metodin suorittaminen Metodista palattaessa metodin paikalliset muuttujat hävitetään Mahdollinen palautettava arvo annetaan kutsujalle Javalla 12
Metodit class Aika { private int tunnit, minuutit, sekunnit; public int gettunnit(){ return tunnit; } public int getminuutit(){ return minuutit; } public int getsekunnit(){ return sekunnit; } } public void settunnit(final int tunti){ tunnit = tunti; } public void setminuutit(final int minuutti){ minuutit = minuutti; } public void setsekunnit(final int sekunti){ sekunnit = sekunti; } Javalla 13
Metodit class AikaTesti { public static void main(string [] args){ Aika tiktak = new Aika(); int tunnit, minuutit, sekunnit; tiktak.settunnit(10); tiktak.setminuutit(22); tiktak.setsekunnit(45); tunnit = tiktak.gettunnit(); minuutit = tiktak.getminuutit(); sekunnit = tiktak.getsekunnit(); } } System.out.println("Aika on: " + tunnit + "." + minuutit + "." + sekunnit); System.out.printf("Aika on: %d.%d.%d%n", tunnit, minuutit, sekunnit); Aika on: 10.22.45 Aika on: 10.22.45 Javalla 14
Metodit Kuormittaminen, metodeilla sama nimi Metodit eroavat kutsumuodoiltaan Parametrien lukumäärä Parametrien tyypit class Aika { private int tunnit, minuutit, sekunnit; public int gettunnit(){ return tunnit; public void lisaatunti(){ tunnit++; } } public void lisaatunti(final int maara){ tunnit = tunnit + maara; } Javalla 15
Metodit n Eri luokissa voi olla samannimisiä ja samantyyppisiä metodeja public class DialogWindow { public void draw() {} } public class Artist { public void draw(){} } Näkymäalueen suhteen ylikuormitetut metodit Javalla 16
Olioiden luonti Ensin täytyy olla olion määrittelevä luokka Olio luodaan luokan kuvauksen perusteella Yleinen muoto new LuokanNimi([parametrit]); Esimerkiksi String nimi = new String( Terve Ilkka! ); Aika tiktak = new Aika(); Javalla 17
Olioiden luonti Alussa määritellään viitemuuttuja Viitemuuttujan tyyppi sama kuin luotavalla oliolla Olio luodaan operaatiolla new Luo uuden olion luokan kuvauksen perusteella, kutsumalla rakentajaa (konstruktoria) Varaa tilaa attribuuteille Alustaa attribuutit oletusarvoilla Lopuksi palauttaa viitteen luotuun olioon Lopuksi viite talletetaan viitemuuttujaaan Javalla 18
Olioiden luonti Rakentajaa (konstruktoria) kutsutaan aina, kun luokasta luodaan olio public LuokanNimi([parametrit]) { alustustoimenpiteet } Rakentajia voi olla useita (kuormitus) Rakentaja voi myös puuttuua, käytetään oletusrakentajaa Ei paluuarvoa kuten muilla metodeilla Rakentajan nimi on aina sama kuin luokan nimi Javalla 19
Olioiden luonti Rakentajan kutsussa parametrien on vastattava rakentajan parametrilistaa, muuten virhetilanne Rakentajaa ei voi käyttää mihinkään muuhun tarkoitukseen Jos rakentajan parametrin nimi on sama kuin alustettavan attribuutin nimi, käytettävä this avainsanaa attribuutin nimen edessä Javalla 20
Olioiden luonti class Aika { private int tunnit, minuutit, sekunnit; public Aika(){ tunnit = 0; minuutit = 0; sekunnit = 0; } public Aika( final int tunnit, final int minuutit, final int sekunnti){ this.tunnit = tunnit; this.minuutit = minuutit; this.sekunnit = sekunnit; } Javalla 21
Olioiden luominen class AikaTesti { public static void main(string [] args){ Aika tiktak1 = new Aika(); Aika tiktak2 = new Aika(23, 11, 33); int tunnit, minuutit, sekunnit; tunnit = tiktak1.gettunnit(); minuutit = tiktak1.getminuutit(); sekunnit = tiktak1.getsekunnit(); System.out.printf("tiktak1 on: %d.%d.%d%n", tunnit, minuutit, sekunnit); tunnit = tiktak2.gettunnit(); minuutit = tiktak2.getminuutit(); sekunnit = tiktak2.getsekunnit(); System.out.printf("tiktak2 on: %d.%d.%d%n", tunnit, minuutit, sekunnit); } } tiktak1 on: 0.0.0 tiktak2 on: 23.11.33 Javalla 22
Oliot, viittaaminen Viitemuuttujat Aika tiktak; tiktak = null; tiktak? tiktak Javalla 23
Oliot, viittaaminen n tiktak1 = new Aika(); tiktak1 :Aika tunnit=0 minuutit=0 sekunnit=0 n tiktak2 = new Aika(23, 11, 33); tiktak2 :Aika tunnit=23 minuutit=11 sekunnit=33 Javalla 24
Oliot, viittaaminen Olion metodeja kutsutaan Viitemuuttuja yksilöi olion, johon viitataan Käytetään pisteoperaattoria olionnimi.metodinnimi(); tiktak1.gettunnit();//palauttaa 0:n tiktak2.gettunnit();//palauttaa 23:n Mitä tapahtuu? tiktak1 = tiktak2; Javalla 25
Olitot, olioon viittaaminen tiktak1 :Aika tunnit=0 minuutit=0 sekunnit=0 tiktak2 :Aika tunnit=23 minuutit=11 sekunnit=33 Javalla 26
Oliot, olioon viittaaminen tiktak1 on tiktak2:n viittaaman olion alias Yhteen olioon voi olla useita viittauksia Javalla 27
Oliot, tuhoaminen Olio johon tiktak1 viittasi ennen sijoitusta muuttuu roskaksi Olio, johon ei ole yhtään viittausta (eli ei ole saavutettavissa) poistetaan automaattisella roskienkeruulla (garbage collection) tiktak2 = null; tiktak2.gettunnit(); //ei toimi NullPointerException virhetilanne Yritys viitata olemattomaan olioon Javalla 28
Character -luokka Yksittäinen merkki voidaan esittää oliona Characterluokan avulla Luokan metodeilla voidaan tutkia merkin ominaisuuksia, kuten onko merkki iso kirjain, aakkonen, numero Javalla 29
Merkkijonot Luokka java.lang.string! Merkkijono luodaan yleensä new operaatoria käyttäen String merkkijono = new String( Kukkahattu );! Kapseloi merkkijonon sisältävät merkit (käyttää taulukkoa) Luokan metodit eivät muuta kohdeolion tilaa (arvokeskeisyys) Muokaaminen tuottaa aina uuden merkkijono-olion Merkkijonovakio lainausmerkkien sisään String omanimi = Ilkka Räsänen ;! Javalla 30
Merkkijonot Operaatioita (lisää löytyy Java Api-dokumentaatiosta) https://docs.oracle.com/javase/8/docs/api/ int length(), palauttaa merkkijonon pituuden char charat(int index), palauttaa merkin indeksin osoittamasta kohdasta, indeksi voi olla 0 length()-1 int compareto(string anotherstring), vertailee ovatko merkkijono ja anotherstringmerkkijono samat, palauttaa luvun nolla, jos merkkijonot ovat samoja, nollaa suuremman arvon, jos merkkijono on aakkosissa ennen parametrina annettua merkkijonoa (huom! ääkköset ) Javalla 31
Merkkijonot Merkkijonoja ei vertailla == -operaattorilla String eka = new String( Auto );! Strint toka = new String( Auto );! if( eka == toka )! else! System.out.println(eka + = + toka);! System.out.println(eka + ei ole + toka);! Ohjelma tulostaa: Auto ei ole Auto Javalla 32
StringBuilder, StringBuffer Merkkijono on arvokeskeinen, eli sitä ei luonnin jälkeen voi muuttaa StringBuilder- ja StringBuffer-luokat ovat muuttujakeskeisiä versioita StringBuilder joku = new StringBuilder( pää );! joku.insert(0, Puu ); //Puupää! joku.append( kö? ); //Puupääkö?! joku.repalace(3,9, kko ); //Puukko! String tulos = joku.tostring();! Javalla 33
Kääreluokat n Javassa alkeistyypit eivät ole olioita n Joissakin tilanteisssa tarvitaan alkeistyypin oliovastinetta n Käytetään kääreluokkaa (wrapper) alkeistyypi boolean char byte short int long float double kääreluokka Boolean Character Byte Short Integer Long Float Double Javalla 34
Kääreluokat Integer intolio = new Integer(10);!! n Tarvittaessa käärintä voi tapahtua automaattisesti n Käärinnän purku int luku = intolio.intvalue();!! n Automaattisen käärimisen käyttö voi vahingossa tuottaa tehotonta koodia! Javalla 35
Kääreluokat import java.io.*;!! public class KaareDemo {! public static void main(string [] args){!! Integer summa = 0;! Integer [] luvut = {1,2,3,4,5};!! summa = laskesumma( luvut );! System.out.println("Lukujen summa on:" + summa.tostring());!! }! public static Integer laskesumma(integer [] luvut){! Integer summa = 0;!! for(integer i = 0; i < luvut.length; i++){! summa = summa + luvut[i];! }! return summa;! }! }! Javalla 36
Kääreluokat n laskesumma metodi käärintöjen purkamisen jälkeen public static Integer laskesumma(integer [] luvut){! Integer summa = new Integer(0);!! for(integer i = new Integer(0);! i.intvalue() < luvut.length;! i= new Integer(i.intValue() + 1)){! summa = new Integer(! summa.intvalue()+luvut[i.intvalue()].intvalue());! }! return summa;! }! n Kannattaa käyttää alkeistyyppiä aina kun se vain on mahdollista Javalla 37
Kääreluokat! try {! String mjono = 1234 ;! int luku = Integer.parseInt( mjono );! double noinpii = Double.parseDouble( 3.14 );! }catch(numberformatexception nfe){! System.out.println( Pieleen meni );! }! System.out.println(nfe.getMessage());! Jos kääreluokan metodi ei osaa käsitellä parametrina annettua tietoa, syntyy poikkeustilanne (NumberFormatException), lisää myöhemmin Javalla 38
Taulukot Ovat olioita Indeksointi kuten C:ssä, alkaa 0:sta Taulukon lopussa taulukon koko, vakio nimeltä length! Viittausmuuttuja int [] luvut;! Hakasulkeet tyypin ja nimen välissä ilmaisevat, että luvut ei ole tavallinen int-tyypin muuttuja, vaan viitemuuttuja, joka voi viitata kokonaislukuja sisätävään tulukkoon luvut Määrittely ei varaa tilaa talletettaville luvuille Javalla 39
Taulukot Tilanvaraus new operaattorilla luvut = new int[6];!!! luvut 0 0 0 0 0 0! Olioviitteitä sisältävä taulukko Aika [] aikoja = new Aika[5];!!! 0 1 2 3 4 5 length 0 1 2 3 4 length aikoja 5 6 Javalla 40
Taulukko Taulukon yksittäiseen alkioon viitataan taulukonnimi[indeksi]!! indeksi on kokonaisluku 0..length-1 luvut[2] = 55;!! Jos indeksi ei ole taulukon rajojen sisällä, syntyy ajonaikainen poikkeustilanne ArrayIndexOutOfBoudsException!! Ohjelman suoritus päättyy välittömästi Javalla 41
Taulukko n Aika-tyyppisen taulukon täyttäminen aikoja[3] = new Aika();! aikoja[4] = new Aika(22, 45,21);!! 0 1 2 3 4 length aikoja 5 0,0,0 22,45,21 Javalla 42
Taulukko n Taulukko välitetään metodille viitteenä, ei kopioida arvoja public static void tulostataulukko( int [] lukuja ){ System.out.println("Luvut:"); } for( int luku: lukuja ){ System.out.println("luku: " + luku); } n Kutsussa vain taulukon nimi, ei tyyppiä eikä hakasulkeita n Metodi voi muuttaa saamansa taulukon arvoja Javalla 43
Taulukko n Taulukon kopiointi System-luokan metodilla arraycopy!! public static void arraycopy(object src, int src_position, Object dst, int dst_position, int length)!! n Moniulotteiset taulukot Javassa ei ole moniulotteisia taulukkoja Ongelma kierretään telemällä taulukko, jossa on viittauksia taulukkoihin Javalla 44
Taulukot int [][] matriisi = new int[3][3];!!! matriisi 0 1 2 length 3 0 1 2 3 3 3 length Javalla 45
Taulukko n Taulukon avulla metodille voi välittää vaihtelevan määrän parametreja n Metodin määrittelyssä viimeinen muodollinen parametri voi olla vaihtelemanmääräinen parametri (variable arity parameter) n Vaihtelemanmääräisiä parametrejä voi olla vain yksi per metodi n Määrittelyssä tämä ilmaistaan kolmella pisteellä parametrin tyypin ja nimen välissä n Kääntäjä generoi taulukon automaattisesti Javalla 46
Taulukko public static void tulosta(string... mjonot){! for(string mojono : mjonot){! if( mjono == null)! System.out.println("null");! else! System.out.println(mjono + " pituus " + mjono.length());! }! }! }! Javalla 47