1 / 47

ict02d Olio-ohjelmointi: Luokkien kirjoittaminen Jukka Juslin

ict02d Olio-ohjelmointi: Luokkien kirjoittaminen Jukka Juslin. Luokkien kirjoittaminen. Tähänmennessä on käytetty valmiiksi määritettyjä luokkia. Nyt opimme kirjoittamaan omia luokkia olioiden määrittämiseksi Seuraavaksi keskitymme näihin: Luokan määritykset Instanssin tieto (olion tieto)

roza
Download Presentation

ict02d Olio-ohjelmointi: Luokkien kirjoittaminen Jukka Juslin

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ict02d Olio-ohjelmointi: Luokkien kirjoittaminen Jukka Juslin

  2. Luokkien kirjoittaminen • Tähänmennessä on käytetty valmiiksi määritettyjä luokkia. Nyt opimme kirjoittamaan omia luokkia olioiden määrittämiseksi • Seuraavaksi keskitymme näihin: • Luokan määritykset • Instanssin tieto (olion tieto) • kapselointi ja tiedon muuttajat (setterit ja getterit) • Metodin määrittäminen ja parametrien välitys • Konstruktorit eli oletusmuodostimet (niiden korvaajat)

  3. Missä ollaan? Luokan anatomia kapselointi Metodin anatomia

  4. Luokkien kirjoittaminen • Luokat, joita olemme aikaisemmin käyttäneet ovat Javan standardi luokkakirjastosta (API) • Nyt alamme suunnitella ohjelmia, jotka perustuvat luokkiin joita itse kirjoitamme (kohdeluokat yms.) • Luokka joka sisältää main metodin on vain ajettavan ohjelman käynnistyspiste • Todellinen olio-ohjelmointi perustuu luokkien määrittämiseen (ei laiteta kaikkea mainin sisään, vain käynnistys!!!). Luokat esittävät olioita hyvin suunnitellun toiminnallisuuden ja attribuuttien kanssa

  5. Luokat ja oliot • Muista että oliolla on aina tila ja käyttäytyminen • Tarkastellaan kuusisivuista noppaa (yhtä noppaa) • Sen tila voidaan määrittää siitä mitä sivua se näyttää ylöspäin • Sen pääasiallinen käyttäytyminen on, että sitä voidaan heittää • Voit ajatella samaa “realimaailmassa” esimerkiksi koskien coca-cola automaattia. Mikä on automaatin tila esim. Ja mikä on automaatin käyttäytyminen? • Voimme esittää noppaa ohjelmistossa suunnittelemalla luokan Noppa tjoka mallintaa nopan tilan ja käyttäytymisen. Tuloksena saadaan noppa, joka on itseasiassa parempi kuin perinteinen noppa. • Luokka toimii noppa olion piirustuksena • Me voimme instantioida niin monta noppa-objektia kuin tarvitsemme missä tahansa ohjelmassa

  6. int koko, paino; char kategoria; Luokat • Luokka voi sisältää tiedon määrityksiä ja metodimäärityksiä Tiedon määritykset Metodi määritykset

  7. Luokat • Tiedon arvot määräävät olion tilan, joka on luokasta luotu • Metodien toiminnallisuus määrittää olion käyttäytymisen • Noppa luokkaamme voisimme määrittää int-tyyppisen muutujan, joka näyttää tällähetkellä ylöspäin osoittavan nopan sivun arvon • Yksi metodeista “heittää” noppaa asettamalla tämän arvon satunnaislukuun, joka on ykkösen ja kuutosen välillä

  8. Luokat • Haluamme suunnitella Noppa luokkaan kaikki tarvittavat tiedot ja metodit, jotta se olisi monikäyttöinen ja uudelleenkäytettävä resurssi – Noppa.java, public class Noppa • Mikä tahansa käyttävä ohjelma (Testeri) ei välttämättä käytä kaikkia ko. Luokan ominaisuuksia

  9. Noppa luokka • Noppa luokka sisältää kaksi arvoa • vakio MAX , joka esittää maksimaalista nopan arvoa • muuttujan nopanArvo joka esittää nopan arvoa tällä hetkellä (ylöspäin oleva sivu heiton jälkeen) • heitä metodi käyttää random metodia Math luokasta määrätäkseen nopan saaman arvon • On myös olemassa metodeita, joilla eksplisiittisesti asetetaan ja noudetaan nopan arvo milloin tahansa

  10. toString metodi • Kaikkien luokkien, jotka esittävät olioita, pitäisi määrittää toString metodi • toString metodi palauttaa merkkijono Stringin, joka esittää olion (tekstimuodossa, oliota ei luonnollisesti voi tulostaa suoraan) • Sitä kutsutaan automaattisesti kun olio konkatenoidaan Stringiin (+ operaatio) tai kun olio välitetään println metodille

  11. Konstruktorit eli oletusmuodostimet • Kuten aikaisemmin mainittu, konstruktori on erityinen metodi, jota käytetään olion alustamiseen, kun se alunperin luodaan • Konstruktorilla on sama nimi kuin luokalla, ei palautusarvoa • Noppa konstruktoria käytetään asettamaan jokaisen uuden noppa olion antamaksi lähtötulokseksi yksi • Myöhemmin tutustutaan konstruktoreihin lisää

  12. Tiedon näkyvyys (skooppi) • Tiedon näkyvyys on alue ohjelmasta, josta tiettyyn tietoon päästään viittaamaan (käyttämään sitä) • Tietoon, joka määritetään luokkatasolla voidaan viitata luokan kaikista metodeista käsin • Tietoon, joka määritellään metodin sisällä, päästään käsiksi vain ko. metodin sisällä • Tietoa, joka määritellään metodin sisällä kutsutaan paikalliseksi tiedoksi / paikalliseksi muuttujaksi • Noppa luokassa muuttuja tulos määritetään toString metodin sisällä – se on pakallinen ko. Metodille ja tulkseen ei voida viitata muualta. Vertaa esimerkiksi taulu-olioiden length attribuuttia, joka on public-tyyppinen ja luokkatasolla

  13. Instanssin tieto eli olion tieto • nopanArvo muuttuja Noppa luokassa kutsutaan instanssin tiedoksi sillä jokainen instanssi (olio) joka luodaan omistaa oman version siitä • Luokka määrittää tiedon tyypin, mutta ei varaa tiedolle mitään muistitilaa • Jokainen kerta kun Noppa olio luodaan, uusi nopanArvo muuttuja luodaan myös • Luokan oliot jakavat metodin määritykset, mutta jokaisella oliolla on oma muistiavaruus • Tämä on ainoa tapa miten kahdella oliolla voi olla erilaiset tilat

  14. nopanArvo 5 noppa1 nopanArvo 2 noppa2 Instanssitieto • Voimme kuvata kaksi Noppa oliota NopanHeitto ohjelmasta kuten seuraavassa: Jokaisella oliolla pitää omaa nopanArvo muuttujaa ja tätä kautta oliolla on oma tila

  15. UML kaaviot eli diagrammit • Kuten aikaisemmasta on tuttua, UML tarkoittaa Unified Modeling Languagea • UML diagrammit näyttävät luokkien ja olioiden väliset suhteet • UML luokkadiagrammi koostuu yhdestä tai useammasta luokasta, joissa jokaisessa on erotetut osiot luokan nimelle, attribuuteille (tiedolle) ja operaatioille (metodeille) • Viivat luokkien välillä (luokkakaaviossa) esittävät yhteyssuhteita eli assosiaatioita. Näistä tutustumme seuraaviin (kahteen) tyyppiin: • Katkoviivalla varustettu nuoli kertoo, että toinen luokka (siis luokasta tehty olio) käyttää toista (eli kutsuu sen metodeja) – kontrolli siirtyy. Näitä katkoviivanuolia käytämme etupäässä, tosin tutustumme myös koostumus-suhteisiin eli aggregaatioihin (joita ilmaistaan ns. Timanttimerkillä)

  16. HeitäNoppaa Noppa -nopanArvo : int +main (args : String[]) : void +heitä() : int +setNopanArvo (int arvo) : void +getNopanArvo() : int +toString() : String UML luokkakaaviot • UML luokka class diagram HeitäNoppaa ohjelmalle:

  17. Missä ollaan? Luokan anatomia Kapselointi Metodin anatomia

  18. Enkapsulointi • Voimme ottaa yhden kahdesta näkökulmasta tarkastella oliota: • sisäinen - luokan muuttujien ja metodien yksityiskohdat, eli luokan määrittäminen • ulkoinen - palvelut, jotka olio tarjoaa ja kuinka olio vuorovaikuttaa muiden järjestelmän olioiden kanssa • Ulkoisestä näkökulmasta, olio on enkapsuloitu entiteetti (eli kokonaisuus), se tarjoaa joukon määritettyjä palveluita • Nämä palvelut määrittävät olion rajapinnan (eli interface), joka näkyy ulospäin

  19. kapselointi • Yksi olio (kutsutaan asiakkaksi (client)) voi käyttää toista oliota, jotta voisi tarjota palvelut jotka sen pitää tarjota • Olion asiakas voi pyytää ko. olion palveluita (eli kutsua olion metodeja), mutta sen ei pitäisi tietää kuinka ko. palvelut suoritetaan. • Vrt. Esim. Coca-Cola automaatin toiminta. Jos käyttäjää ajatellaan oliona, hän haluaa vain Coca-Colaa eikä välittää automaatin sisäisestä toiminnasta. • Mikä tahansaa muutos olion tilassa (sen muuttujissa) pitää tehdä olion metodien kautta (eli tavallisesti set ja get metodit) • Huomaa myös poikkeukset tästä esim. Taulukko-luokkien length-attribuutti (public) • Meidän pitää tehdä vaikeaksi, ellei jopa mahdottomaksi, asiakaan päästä käsiksi olion muuttujiin suoraan (kuten taulukko-olion length) • Eli, olioiden pitäisi olla itsehallintoon perustuvia (self-governance)

  20. Metodit Asiakas Tieto kapselointi • Enkapsuloitua oliota voidaan ajatella mustana laatikkona – sen sisäinen toiminta peitetään asiakkailta • Asiakas kutsuu rajapintametodeja (tavalliset public-tyyppiset metodit) – nämä hallitsevat instanssin tietoa

  21. Näkyvyyden muuntelu • Javassa, me saavutamme kapselointin käyttämällä sopivia näkyvyysmääritteitä (visibility modifiers) • näkyvyysmäärite on Javan varattu sana, joka määrittää tietyn metodin tai muuttujan luonteen • final määritettä käytetään vakioiden määrittämiseen (esim. private final EUROTOMARK = 5.94) • Javassa on kolme näkyvyyden muuntelumäärettä: public, protected ja private • protected määre liittyy periytymiseen, jota käsittelemme opintojaksomme osiossa kolme. Tehtävissä, emme käytä ko. määrettä tässä osiossa.

  22. Näkyvyyden määritteet • Luokan osiin (attribuutit tai metodit), jotka määritetään julkisiksi (public visibility) voidaan viitata mistä tahansa käsin • Luokan osiin (attribuutit ja metodit), jotka määritetään yksityisiksi (private visibility) voidaan viitata ainoastaan ko. luokan sisältä • Luokan osiin (attribuutit ja metodit), joille ei anneta näkyvyyttä (visibility) ollenkaan, annetaan oletusarvoinen näkyvyys (default visibility) ja näihin voidaan viitata mistä tahansa luokasta samassa paketissa

  23. Näkyvyyden määrittäminen • Julkiset muuttujat rikkovat kapselointiperiaatetta vastaan, sillä ne mahdollistava sen että asiakas pääse käsiin ja voi voi muutella luokan attribuuttien arvoja • Siksi luokan muuttujia ei saisi määrittää julkisen näkyvyyden kanssa (eli siis pitää aina käyttää private sanaa ennen muuttujan nimeä) • On hyväksyttävää antaa vakiolle (public final MAX) julkinen näkyvyys, jolloin sitä voidaan käyttää (mutta ei muuttaa) luokan ulkopuolelta • Julkiset vakiot eivät riko kapselointiperiaatetta vastaan, sillä vaikka asiakkaalla on pääsy näihin vakioihin, asiakas ei voi muuttaa niiden arvoa (kun final määre käytössä!)

  24. Näkyvyyden määrittäminen • Metodit, jotka tarjoavat olion palvelut määritetään julkisen näkyvyyden (public visibility) kanssa, jotta niitä voidaan kutsua asiakkaista käsin • Esim. annaCocaCola(1) // määräys • Julkisia metodeja kutsutaan myös palvelumetodeiksi (service methods) • Metodia, joka luodaan pelkästään auttamaan palvelumetodia kutsutaan tukimetodiksi (esimerkiksi pudotaPullo()) • Koska tukimetodia ei kutsuta asiakkaasta käsin, se pitää määrittää tyypillisesti private näkyvyyden kanssa

  25. public private Muuttujat, attribuutit Metodit Näkyvyysmääritteet Rikkovat enkapsulointia Tukevat enkapsulointia Tukevat luokan muita metodeja Tarjoavat palveluja asiakkaille

  26. Aksessorit ja mutaattorit – eli getterit ja setterit • Koska instanssitieto on yksityistä (private), luokka yleensä tarjoaa palveluita muuttujien arvojen lukemista ja päivittämistä varten • Aksessorimetodi (accessor method) palauttaa muuttujan nykyisen arvon (lukee muuttujan arvon) - kutsutaan myös gettereiksi • Mutaattori metodi (mutator method) muuttaa muuttujan arvoa (päivittää muuttujan arvoa) – kutsutaan myös settereiksi • Nimet aksessori ja mutaattorimetodeille ovat muotoa getX ja setX, jossa X on arvon nimi (esim. setOppilasNumero(numero) • Näitä kutsutaan aksessorin ja mutaattorin sijasta monasti “gettereiksi” ja “settereiksi”

  27. Mutaattorin rajoitukset • Mutaattorien käyttö antaa luokan suunnittelijalle mahdollisuuden rajoittaa asiakkaan mahdollisuuksia muutella olion tilaa (muuttujien arvoja suoraan, setteriin voi laittaa esim. tarkistuksen minkälainen luku on kyseessä) • Mutaattori suunnitellaan usein niin, että muuttujien arvot voidaan asettaa vain tietyissä rajoissa. Esimerkiksi tilin omistajan nimi voidaan rajata max 50 merkkiin – sillä tietokannassa jossa tietoja lopulta säilytetään on todennäköisesti kokorajoitus • Esimerkiksi setNopanArvo mutaattori Noppa luokassa pitäisi rajoittaa niin, että arvo voidaan asettaa ainostaan johonkin tasalukuun sallitulla arvoaluella (tässä 1:stä MAX vakion arvoon asti) • Myöhemmin tutustumme tarkemmin siihen miten tällaisia rajoituksia toteutetaan

  28. Luokkien kirjoittaminen - this • Muista this-avainsanan käyttö • This-sanalla viitataan olion attribuuttiin • Ilman this sanaa metodille tulevat parametrit on nimettävä erinimisiksi kuin luokan attribuutit

  29. Lisää this-sanasta • This-viittaa aina kyseisellä hetkellä käytössä olevaan olioon • Koko nykyinen olio voidaan palauttaa kirjoittamalla return(this);

  30. toString metodi • Pääsääntöisesti kaikille luokille pitää kirjoittaa toString metodi • toString konkatenoi Stringiksi olion attribuuttien arvon tällähetkellä • Eli kyseessä on ns. olion tilan tulostaminen • Ilman toString metodia saadaan oliosta tulostumaan ns. OID numero, joka on muistiosoite viitaten missä itse olio sijaitsee

  31. Missä ollaan? Luokan anatomia kapselointi Metodin anatomia

  32. Metodin määrittämiset • Katsomme seuraavassa metodin määrittämistä hiukan tarkemmin • Metodin määrittely määrää koodin, joka tullaan suorittamaan kun metodia kutsutaan • Kun metodia kutsutaan, kontrolli (ns. etenemisrivi) ohjelmassa hyppää ko. Metodiin ja suorittaa ko. metodin koodin. Tämän suorittaminen loppuu kun tullaan return-lauseeseen. • Kun tämä valmistuu, kontrolli palaa takaisin sinne mistä metodia kutsuttiin (voi tehdä esim. sijoituksen) ja jatkaa seuraavalta riviltä • Metodi voi palauttaa tai olla palauttamatta arvon, riippuen kuinka metodi on määritetty

  33. laske munMetodi munMetodi(); Metodin kontrollivirta • Jos kutsuttu metodi on samassa luokassa tarvitaan vain metodin nimi kutsumiseen

  34. main teeSe autaMua olio.teeSe(); autaMua(); Metodin kontrollivirta • Kutsuttu metodi on usein osa toista luokkaa tai oliota (siis nimenomaan oliota yleensä, ellei static)

  35. Metodin headeri • Metodin määritys alkaa metodin headerilla char laske(int num1, int num2, String viesti) metodinnimi parametrilista Parametrilista määrittää jokaisenparametrin tyypin ja nimen Parametrin nimeä metodin määrittelyssäkutsutaan formaaliksi parametriksi. Ko.muuttujat luodaan aivan kuten metodin sisällä luodaan muuttujia. palautustyyppi

  36. Metodin runko • Metodin headeria eli otsikkoa seuraa metodin runko (method body). Muista: Headerissa on määritetty myös formaalit parametrit. char laske(int num1, int num2, String viesti) { int sum = num1 + num2; char tulos = viesti.charAt (sum); return(tulos); } sum and tulos ovat paikallista tietoa tähän metodiin Nämä muuttujat luodaan aina kun tätä metodia kutsutaan, ja ne tuhotaan kun metodin suoritus loppuu Returnissa palautettavan Olion tulee olla palautus-tyyppiä eli samaa kuinmetodin headerissa

  37. return lause • Metodin palautustyyppi määrää minkätyyppisen arvon metodi lähettää takaisin sinne, mistä metodia on kutsuttu • Metodilla, joka ei palauta arvoa on void palautustyyppi (metodin formaalissa esittelyssä) • return lause määrää mikä arvo metodista palautetaan return(olio); • Olion on tässä oltava samaa tyyppiä kuin formaalissa esittelyssä määritetty tyyppi ja kutsumispaikassa olio tulee sijoittaa esim. samantyyppiseen muuttujaan

  38. char laske (int num1, int num2, String viesti) { int sum = num1 + num2; char tulos = viesti.charAt (sum); return tulos; } Parametrit • Kun metodia kutsutaan, varsinaisten parametrien arvot kutsun yhteydestä kopioidaan formaaleiden parametrien arvoiksi ch = olio.laske (25, count, “Moro");

  39. Paikallinen data eli paikallinen tieto • Kuten olemme huomanneet, paikalliset muuttujat voidaan määrittää metodin sisällä • Metodin formaalit parametrit luovat automaattisia paikallisia muuttujia kun metodia kutsutaan • Kun metodi lopettaa toimintansa, kaikki paikalliset muuttujat tuhotaan (mukaanlukien formaaleista parametreistä tehdyt muuttujat) • Pidä mielessä, että instanssimuuttujat, luokan tasolla määritetyt, ovat olemassa niinkauan kuin olio on olemassa

  40. Pankkitiliesimerkki • Katsotaan toista esimerkkiä, joka demonstroi toteutusyksityiskohdat luokista ja metodeista • Esitämme pankkitilä luokalla, jonka nimi on Tili • Pankkitilin tila voi sisältää pankkitilin numeron, saldon tällähetkellä ja tilin omistajan nimen • Tilin käyttäytyminen (tai sen palvelut) sisältävät otot ja talletukset sekä koron lisäämisen tilille

  41. Testeriohjelmat • Testeriohjelma eli ajuriohjelma ajaa toisia, kiinnostavampia osia ohjelmasta • Testeriohjelmia käytetään usein testaamaan muista osia ohjelmasta • Testeriohjelma sisältää luonnollisesti main-metodin, aloittaa siis ajettavan • Transaktion luokka sisältää main metodin, joka ajaa Tili luokan, kokeillen sen palveluita

  42. tili1 72354 tilNumero 102.56 saldo nimi “Matti Nykänen” tili2 69713 tiliNumero 140.00 saldo “Pekka Pere” nimi Pankkitili esimerkki

  43. Pankkitili esimerkki • On olemassa joitain parannuksia, joita voidaan tehdä Tili luokkaan • Muodolliset getterit ja setterit pitäisi määrittää kaikille muuttujille • Joidenkin metodien design voisi olla robustimpi (vankempi), kuten todentaa että määrä parametri nosto metodille on positiivinen • saldo - nosto

  44. Konstruktorit - lisää • Huomaa, että konstruktorilla ei ole palautustyyppiä määritetty metodin headeriin (formaaliin määritykseen) – ei edes void tyyppiä! • Yleinen virhe on laittaa konstruktorille palautustyyppi, mikä tekee siitä “tavallisen” metodin, jolla sattuu olemaan sama nimi kuin ko. luokalla • Ohjelmoijan ei tarvitse määrittää konstruktoria luokalla (eli oletuskonstruktori on jo olemassa, kyse on sen korvaamisesta) • Jokaisella luokalla on valmiiksi Javan tekemä oletuskonstruktori eli oletusmuodostin (default constructor) joka ei ota parametrejä(muista kuitenkin myös konstruktorin ylikuormittaminen) • public Pvm() // esimerkki oletuskonstruktorista

  45. Konstruktoreista • Synonyymi konstruktori-sanalle on muodostin • On tärkeää osata seuraavat käsitteet: • Oletuskonstruktori (oletusmuodostin) • Korvaa Javan oletusarvoisen konstruktorin – ilman parametrejä() olevan konstruktorin • Parametrillinen konstruktori (parametrillinen muodostin) • Saa vaihtelevan määrän parametrejä • Kopiokonstruktori (kopiomuodostin) • Saa parametrinä oman luokan olion ja kopio olion nykyiseen olioon (eli tekee kopin)

  46. Missä ollaan? Luokan anatomia kapselointi Metodin anatomia Selvisimme tästä, seuraavaksi yhteenveto

  47. Yhteenveto • Tutustuimme • Luokan määrittämiseen • Instanssidataan (attribuutit) • kapselointi ja Java määreet (private ja public) • Metodin määrittäminen ja parametrien välittäminen • Konstruktorit

More Related