410 likes | 536 Views
Metodit – Arvotyyppi. Ellei metodi palauta arvoa, sen arvotyyppi on void Tällöin ”return;”-lauseke ei ole metodissa pakollinen, vaikka sen käyttö on sallittua Metodi voi palauttaa alkeistyypin tai olion
E N D
Metodit – Arvotyyppi • Ellei metodi palauta arvoa, sen arvotyyppi on void • Tällöin ”return;”-lauseke ei ole metodissa pakollinen, vaikka sen käyttö on sallittua • Metodi voi palauttaa alkeistyypin tai olion • Tällöin ”return X;”-lauseke on pakollinen. Metodissa ei saa olla suorituspolkuja, joilla return-lausekkeeseen ei päädytä. X on palautettava arvo, joka on arvotyypin tyyppinen.
Metodit – Arvotyyppi • Esimerkkipublic static String viikonpaiva(int luku) { switch(luku) { case 1: return ”Ma”; case 2: return ”Ti”; ... } return ””;}
Metodit – Parametrit • Parametrit annetaan sulkeissa • Alkeistyypit ovat arvoparametreja • Arvon muuttaminen metodin sisällä ei muuta alkuperäistä arvoa • Oliot ovat viiteparametreja • Saman olion käyttö metodin sisällä muuttaa myös alkuperäistä arvoa
Metodit – Parametrit • public static void test(int i, String s, Student r) { i=0; s=”Muutettu”; r.setName(”Pekka”);}...// Esimerkkikutsuint j=1; String t = ”A”; Student u = new Student(”B”);test(j, t, u);System.out.println( ”Tulos: ” + j +” ”+ t + ” ” + u.getName());// Tuloste: ”Tulos: 1 A Pekka”!
Metodit – Kuormittaminen • Samannimisiä metodeja voidaan toteuttaa eri parametreilla • Paluuarvojen tulee samannimisillä metodeilla olla aina samat • Samannimisten metodien toteuttamista eri parametreilla kutsutaan metodin kuormittamiseksi
Metodit – Kuormittaminen • Esimerkkipublic void tulosta(final int luku) { System.out.println( luku );}public void tulosta(final String str) { System.out.println( str );}...// Kutsuesimerkkitulosta(12); // Käyttää ylemää metodiatulosta(”Teksti”); // Käyttää alempaa metodia
Metodit – Rekursio • Jos ohjelmassa on metodi, joka kutsuu sisällään itseään uudestaan, käytetään siitä nimitystä rekursiivinen metodi • Rekursiiviset metodit kutsuvat itseään eri parametreilla • Parametrien perusteella metodi kutsuu itseään tai mikäli ollaan päästy perustapaukseen ei kutsua enää suoriteta
Metodit – Rekursio • Rekursiossa jokaisella kutsulla lähestytään aina jotakin perustapausta • Rekursio on perinteisissä proseduraalisissa ja olio-ohjelmointikielissä hidasta • Teoriassa kaikki rekursiiviset metodit voidaan purkaa auki iteratiivisiksi versioiksi • Rekursiota rajoittaa suurissa tapauksissa käytössä oleva muistin määrä
Metodit – Rekursio – Fibonaccin luvut • Fibonaccin lukuja ovat: 0, 1, 1, 2, 3, 5, 8, 13, ... • Ensimmäinen luku on 0, toinen luku 1 ja siitä eteenpäin seuraava luku saadaan aina kahden edellisen summana • Fibonnaccin lukuja voidaan laskea rekursiivista metodia hyväksikäyttäen • Huomattavasti tehokkaampiakin menetelmiä on olemassa
2 fib(4) 1 1 fib(3) fib(2) 0 1 fib(2) fib(1) Metodit – Rekursio – Fibonaccin luvut // Palauttaa n:nnen Fibonaccin luvun public int fib(int n) { if (n==1) return 0; else if (n==2) return 1; else return fib(n-1) + fib(n-2); } Esim: fib(4)
Näkyvyysalueet ja muuttujien elinaika private, public paikalliset muuttujat
Näkyvyysalueen valinta • Ohjelmissa kannattaa aina valita mahdollisimman pieni näkyvyysalue jokaiselle muuttujalle ja metodille • Kaikki luokan attribuutit kannattaa sijoittaa private-näkyvyysalueeseen • Luokan yleiseen käyttöön tarkoitetut metodit sijoitetaan public-näkyvyysalueeseen, kaikki muut private-näkyvyysalueeseen • Lisäksi on olemassa protected-näkyvyysalue, joka on ikään kuin public:n ja private:n välimaastossa oleva. Käyttö on tarpeellista lähinnä kun hyödynnetään perintää.
Paikallinen muuttuja vai luokan attribuutti • Muuttujat sijoitetaan aina pienimpään mahdolliseen käyttöalueeseensa. • Mikäli muuttujan käyttö on tarpeellista monissa luokan metodeissa tai se kuvaa olion tilaa, tehdään siitä attribuutti. • Mikäli käyttö on tarpeellista vain yksittäisessä metodissa, käytetään paikallista muuttujaa.
Paikallisen muuttujan määrittely - esimerkki • Paikallinenkin muuttuja kannattaa sijoittaa aina mahdollisimman rajattuun alueeseen. • Esimerkki: public void printMembers() { Vector members = getAllMembers(); for (int i=0;i<members.size();i++) { Member member = members.getAt(i); String name = member.getName(); System.out.println(”Jäsen: ” + name); } } Muuttujien esittelyt voitaisiin sijoittaa katkoviivalla osoitettuun paikkaan, mutta koska niitä ei käytetä kuin toistorakenteen sisällä, on ne sijoitettu toiston sisältämän lohkon sisään.
Muuttujien elinaika • Jokaisella muuttujalla on näkyvyysalueen lisäksi ns. elinaika, jolloin se on olemassa • Luokkamuuttujat on olemassa aina kun olion konstruktoria on kutsuttu, olemassaolo loppuu kun olioon ei ole enää yhtään viitettä • Paikalliset muuttujat ovat olemassa lohkonsa sisällä. Kun lohko päättyy, paikallisen muuttujan elinaika päättyy.
Taulukot Taulukoiden määrittely, käsittely ja kopiointi Vaihtoehdot taulukoille
Taulukot • Usein on tarvetta käsitellä ryhmää samantyyppisiä olioita tai perustietotyyppejä • On raskasta ja virhealtista kirjoittaa esimerkiksi kymmeniä samantyyppisiä muuttujia peräkkäin ja suorittaa niille kaikille samaa operaatiota • Apua tuovat taulukot, joissa yhteen muuttujaan pystytään sijoittamaan useita olioita
Yksiulotteinen taulukko • Yksiulotteinen merkkijonotaulukko esitellään ja luodaan: String[] names = new String[4]; • Rivi varaa tilan neljälle String-tyyppiselle oliolle. Se jättää kuitenkin kaikki oliot null-arvoiksi. • Mikäli taulukko on luotu jostakin perustietotyypistä, ovat taulukon indeksit suoraan käytössä (ei tarvitse new:llä luoda joka paikkaan oliota) • Taulukon indeksointi alkaa aina nollasta.
0 null 1 null 2 null 3 null Yksiulotteinen oliotaulukko • Oliotaulukon sisältö olisi luonnin jälkeen: • Taulukon yksittäiseen olioon voidaan viitata []:n avulla: names[0] = new String(”Pekka”); • Edellinen rivi luo taulukon ensimmäiseen paikkaan uuden merkkijono-olion
Yksiulotteinen taulukko • Yksiulotteisen taulukon kokoa voidaan muuttaa vain luomalla uusi taulukko. • Taulukon kokoon saa length:llä: int size = names.length; • Taulukon sallittuja sijoitus- ja lukupaikkoja ovat [0..length-1]. Mikäli yritetään käyttää muita paikkoja, heittää Java ajonaikaisen virheen.
Yksiulotteinen oliotaulukko • Käytettäessä String-luokkaa, voidaan kirjoittaa hieman lyhyemmin: names[0] = ”Pekka”; koska Java luo automaattisesti ””:lla erotetusta merkkijonosta uuden String-olion
Taulukon alustaminen • Taulukkoon voidaan sijoittaa arvoja luonnin yhteydessä: final int[] daysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
Yksiulotteinen taulukko - esimerkki String[] students = new String[3]; students[0] = new String(”Matti”); students[1] = new String(”Maija”); students[2] = new String(”Antti”); for (int i=0;i<students.length;i++) { System.out.println(students[i]); }
Yksiulotteinen taulukko – esimerkki 2 private String [] m_students; public void createStudents() { m_students = new String[3]; m_students[0] = new String(”Matti”); m_students[1] = new String(”Maija”); m_students[2] = new String(”Antti”); } public void printStudents() { for (int i=0;i<m_students.length;i++) { System.out.println(m_students[i]); } }
Taulukon käyttöongelma • Koon muuttaminen ei ole yksinkertaista • Soveltuu huonommin tilanteisiin, joissa kokoa ei tunneta ennalta tai koko muuttuu usein
Taulukon koon muuttaminen public class StudentArray { private String [] m_students; public StudentArray() { setArraySize(3); m_students[0] = new String(”Matti”); m_students[1] = new String(”Maija”); m_students[2] = new String(”Antti”); } public void setArraySize(int newSize) { String[] newArray = new String[newSize]; int minLength; if (m_students.length<newSize) minLength = m_students.length; else minLength = newSize; for (int i=0;i<minLength;i++) { newArray[i] = m_students[i]; } m_students = newArray; } }
[0] [1] [2] [3] [0] [1] Moniulotteiset taulukot • Taulukot voivat olla moniulotteisia, koska yksittäinen taulukon alkio voi sisältää toisen taulukon
[0] [1] [2] [3] [0] [1] Moniulotteiset taulukot • Esimerkiksi kaksiulotteinen taulukko: String[][] stringArray = new String[2][4]; stringArray[0][0] = new String(”Ruutu (0,0)”); stringArray[0][1] = new String(”Ruutu (0,1)”); int sizeX = stringArray.length; // == 2 int sizeY = stringArray[0].length; // == 4 String oneItem = stringArray[1][2];
Kokonaislukutaulukon järjestäminenlisäyslajittelu public void insertionSort(int [] intArray) { for (int i=1;i<intArray.length;i++) { int tmp = intArray[i]; int j = i; while (j > 0 && intArray[j-1] > tmp) { intArray[j] = intArray[j-1]; j--; } intArray[j] = tmp; } }
Vector-luokka • Vector-luokalla voidaan toteuttaa samat toiminnot kuin taulukolla. Lisäksi sillä on monia muita helpottavia ominaisuuksia. • Kopiointi • Koon muuttaminen • Lisäys, poisto • Vector-luokka löytyy java.util-paketista (import java.util.Vector)
Vector-luokka – esimerkki import java.util.Vector; ... Vector vector = new Vector(); vector.add(”Pekka”); vector.add(”Tomppa”); vector.remove(0); String firstItem = (String)vector.get(0); vector.add(”Satu”); for (int i=0;i<vector.size();i++) { System.out.println( (String)vector.get(i) ); }
Tiedostojen käsittely Tiedoston luku ja tallennus Poikkeusten käsittely Tietovirrat Oliot tiedostoissa
Tiedostot • Tiedostojen käyttöä tarvitaan kun halutaan esimerkiksi säilyttää tietoa eri ohjelman ajokertojen välillä • Rekisterit • Asetustiedostot • Tulosteet
Tiedostot • Tiedostoja käsitellään Javassa tietovirtojen kautta • Vastaavia tietovirtoja käytetään Javassa komentoikkunaan tulostukseen ja verkon yli tapahtuvaan tiedonvälitykseen
File +File(String) +boolean canRead() +boolean canWrite() +boolean exists() +String getAbsolutePath() +boolean isFile() +boolean isDirectory() +boolean length() +boolean createNewFile() +boolean delete() +boolean mkdir() ... File-luokka • Javan File-luokka sisältää yksittäisen tiedoston tai hakemiston käsittelyyn liittyviä toimintoja • File-luokka löytyy java.io-paketista (import java.io.File)
File-luokka – esimerkki import java.io.File; ... File file = new File(”phonebook.txt”); if (!file.exists()) { if (file.createNewFile()) System.out.println(”File created succesfully.”); else System.out.println(”Couldn’t create file.”); } else { System.out.println(”File phonebook.txt already exists.”); } Esimerkki vaatii toimiakseen poikkeusten käsittelyn.
Poikkeukset • Tiedostojen käsittelyssä voi tapahtua monentyyppisiä virheitä • Oikeudet järjestelmässä • Levytila • Tiedostojen olemassaolo • Virheiden helppoa hallinnointia varten on Java-kielessä käytössä poikkeukset
Poikkeukset • Poikkeukset ovat olioita, joita ohjelmakoodista voidaan heittää (throw) • Poikkeukset on otettava kiinni koodissa (catch) • Poikkeuksia sisältävän koodin suoritus tehdään try-catch -lohkossa
Poikkeukset tiedostojen käsittelyssä • Tiedostojen käsittelyssä File-luokka voi heittää IOException-tyyppisen poikkeuksen (löytyy java.io.IOException-paketista) • Kääntäjä ei käännä koodia ellei poikkeuksia ole otettu kiinni
Poikkeusten käsittely import java.io.*; ... try { // Poikkeuksia mahdollisesti aiheuttava koodi tähän } catch (IOException e) { // Poikkeuksen käsittely }
Poikkeusten käsittely • Javan API-luokkien metodien heittämät poikkeukset on kuvattu Javan API-dokumentaatiossa • Poikkeusten kiinniotto kuuluu kurssin sisältöön, mutta niiden heittäminen ei