Kurssin viimeisimmän version löydät täältä: O1: 2024
Luku 2.1: Olio-ohjelmointi
Tästä sivusta:
Pääkysymyksiä: Miten kuvaan ohjelman aihepiirin tietokoneelle? Miten jäsennän isomman ohjelmakokonaisuuden osiksi — olioiksi — jotka toimivat yhteen? Miten komennan oliota Scalalla?
Mitä käsitellään? Ohjelmointi käsitteiden mallintamisena. Olio-ohjelmointi: oliot ja metodit, olioiden välinen viestintä. Yksittäisoliot Scalassa: metodin kutsuminen, viittaukset olioihin.
Mitä tehdään? Ensin luetaan. Lopussa myös kokeillaan olioiden käyttöä konkreettisesti koodissa.
Suuntaa antava työläysarvio:? Vajaat pari tuntia, jos — kun — käyt kaikki esimerkit ajatuksella läpi. Luku voi olla haastava: olio-ohjelmoinnin peruskäsitteet saattavat ensi alkuun tuntua abstrakteilta tai muuten vierailta.
Pistearvo: A25.
Oheismoduulit: Oliointro (uusi).
Johdanto
Olet tähän mennessä oppinut erilaisia ehkä hieman sekalaisiltakin tuntuvia ohjelmointitekniikoita: lausekkeet, muuttujat, viittaukset, funktiot, tietotyypit ja niin pois päin.
Unohda ne nyt hetkeksi.
Tässä luvussa vaihdamme näkökulmaa ja tarkastelemme laajemman ohjelmakokonaisuuden laatimista sekä sitä ohjelmointitapaa, jota tällä kurssilla käytämme ohjelmien jäsentämiseen: olio-ohjelmointia.
Voidaan ajatella, että kaikki aiemmat luvut ovat olleet eräänlainen alkusoitto sille työlle, joka alkaa tästä luvusta ja jatkuu läpi kurssin. Jo tämän luvun lopussa alkaa paljastua, miten aiemmin opitut asiat liittyvät tämän luvun aiheeseen. Itse asiassa nuo aiemmat aiheet oli valittu alkusoiton säveliksi juuri siksi, että niistä on hyötyä olio-ohjelmoinnin käytännön oppimisessa.
Kurssi alkaa tästä.
Käsitteiden mallintaminen
Kommunikaatio-ongelma
Ohjelmat käsittelevät monimuotoista dataa. Pelkät kokonaislukujen laskutoimitukset, merkkijonojen yhteen liittämiset tai ympyrän piirtämiset eivät riitä. Haluamme, että ohjelmamme "tallentaa tiedoston", "ilmoittaa opiskelijan kurssille", "lisää hotellikokemuksen päiväkirjaan", "reagoi nappulan painallukseen", "nostaa rahaa tililtä" tai "valitsee vihollisen seuraavan siirron".
Kohtaamme ongelman. Ihmisajattelu ja -kieli on käsitteellistä, mutta tietokone ei ymmärrä reaalimaailman käsitteitä. Mikä on "kurssi", "opiskelija", "hotelli" tai "pankkitili"?
Ohjelmointikieli ei voi sisältää yksiselitteisiä määrittelyjä kaikille maailman käsitteille. Silti kone tarvitsisi yksiselitteiset määritelmät voidakseen suorittaa aihepiiriin liittyviä ohjelmia.
Ongelman ratkaisu
Ollaan ihmislähtöisiä: laaditaan ohjelmia, jotka ovat koneen käsiteltävissä mutta jotka heijastavat sitä, miten olemme ihmisinä jäsentäneet ohjelman "maailman". Määritellään tarvitsemamme käsitteet ja niitä vastaavat termit tietokoneelle!
Tarkoituksenamme on siis laatia malli siitä, mitä erilaiset ohjelmamme aihealueeseen (domain) liittyvät käsitteet ovat eli mitä tietoa ja toimintoja niihin liittyy. Koska ohjelmointikieleen itseensä ei voi kirjata kaikkia käsitteitä, on kielen tarjottava mahdollisuus käsitteiden kuvaamiseen.
Olio-ohjelmointi, eräs ohjelmointiparadigma
Vuosien saatossa on syntynyt erilaisia tapoja ohjelmoida, niin sanottuja ohjelmointiparadigmoja (programming paradigm). Ohjelmointiparadigmat eroavat toisistaan muun muassa siltä osin, millaisia työkaluja niissä käytetään asioiden mallintamiseen.
paradigma: perusnäkemys tai viitekehys, jota sen puitteisiin sopeutuva toiminta ei aseta kyseenalaiseksi
—eräs määritelmä sanalle "paradigma" WSOY:n Ison tietosanakirjan pohjalta
Tällä kurssilla keskipisteessä on eräs paradigma: olio-ohjelmointi (object-oriented programming, OOP). Olio-ohjelmointi on suosittu ja mielenkiintoinen ohjelmointiparadigma. Scala on eräs olio-ohjelmointiin hyvin sopiva kieli.
Paradigmat O1-kurssilla
Jotkin ohjelmointiparadigmat ovat toisilleen vaihtoehtoisia, mutta kaikki eivät suinkaan ole toisiaan pois sulkevia; on mahdollista tukeutua useaan paradigmaan yhtä aikaa. Esimerkiksi Scala-kieli on tarkoituksellisesti suunniteltu niin, että sillä voi ohjelmoida erilaisilla tavoilla ja helppoa myös yhdistellä eri tapoja. Tällä kurssilla yhdistämme olio-ohjelmointiin enimmäkseen imperatiivista ohjelmointia (imperative programming) mutta myös funktionaalista ohjelmointia (functional programming). Näistä toisista paradigmoista lisää myöhemmin luvussa 11.2.
Kurssilla syleilemme olioita melko estottomasti. Olio-ohjelmoinnilla on hienoja piirteitä. Silti on hyvä jo alustavasti tiedostaa, että se ei ole kaikkeen aina parhaiten tepsivä poppakonsti. Olio-ohjelmoinnin vaihtoehtoja kohtaat muilla ohjelmointikursseilla (ja lyhyesti luvussa 11.2).
Olio-ohjelmoinnissa korostuu ajatus käsitteiden mallintamisesta. Yksittäistä kurssia, opiskelijaa, pankkitiliä, käyttöliittymäikkunaa tai -nappulaa vastaa olio-ohjelmassa yksi "olio".
Oliot
Mikä on yhteistä kalalle, trumpetille ja piipulle?Entäpä mitä on hyvyys ja kampela?Asioitapa tietenkin ovat ne. — —Maailma on asioita pullollaan!—Ultra Bra
object: something mental or physical toward whichthought, feeling, or action is directed—Merriam-Webster Online
Olio ("asia", "objekti"; object) on jonkin asian kuvaamiseen käytetty abstraktio olio-ohjelmassa. Yleensä kuhunkin olioon liittyy toimintoja eli metodeita (method), joilla oliota voi hyödyntää. Esimerkiksi autoa voitaisiin kuvata oliona, jolla on metodeja kuten "aja", "lisää matkustaja", "tankkaa", "kerro bensan määrä" ja niin edelleen.
Olioon liittyy usein myös ominaisuuksia, jotka kuvaavat sen pysyviä tai muuttuvia piirteitä. Esimerkiksi auto-olion tietoja voisivat olla sen merkki, bensatankin sisältämän bensan määrä, sijainti ja matkustajat.
Ohjelmoija valitsee, mitä ominaisuuksia ja metodeita olioihin liittyy. Valintaperusteena on se, mitkä asiat on tarpeen mallintaa käsillä olevan ongelman ratkaisemiseksi. Esimerkiksi auton valmistaja voi olla merkityksellinen tieto jossakin ohjelmassa mutta merkityksetön toisissa. Kun tietokone suorittaa ohjelman, se pitää olioita tallessa muistissaan ohjelmoijan määrittelemällä tavalla.
Jotakuinkin mitä tahansa voi kuvata oliona. Tässä muutamia esimerkkejä graafisessa muodossa:
Kuvastakin näkyy, että olioilla on sekä tietoja, jotka niihin liittyvät (esim. opiskelijaolion opiskelijanumero, nappulaolion teksti), että toimintoja, joita niihin voi kohdistaa (esim. opiskelijan lisääminen kurssille, tiedoston poistaminen). Huomaa myös, että oliot voivat muistuttaa toisiaan — olla keskenään samaa tyyppiä — kuten kaksi eläinoliota yllä.
Olioista koostuvat mallit
Olioita yhdistelemällä voimme luoda ohjelman aihepiiriä kuvaavan mallin. Tässä pieni esimerkki piirroksen muodossa:
Kullakin oliolla on oma vastuualueensa ohjelman toiminnassa. Esimerkiksi kurssiolion vastuulla voi olla kirjanpito siitä, keitä kurssille on ilmoittautunut, sekä uusista ilmoittautumisista huolehtiminen enimmäisosallistujamäärän puitteissa. Eri olioiden toimintoja yhdistelemällä saadaan aikaan koko ohjelman toiminta.
Olioilla voi myös mallintaa ohjelman käyttöliittymää. Ajatellaan vaikkapa tämän näköistä käyttöliittymäikkunaa:
Tätä ikkunaa voi kuvata Scala-ohjelmassa olioista koostuvalla mallilla, joka näyttää suunnilleen tältä:
Oliot “ihmismäisinä toimijoina”
Olio-ohjelmoinnin ymmärtämisessä voi auttaa ajatusleikki, jossa oliot mielletään ihmismäisiksi toimijoiksi. Kukin olio on, jos ei "älykäs", niin ainakin "kyvykäs" omalla rajallisella tavallaan.
Kukin olio "tietää", millainen se itse on, eli tuntee omat ominaisuutensa. Esimerkiksi auto-olio tietää tankissa olevan bensan määrän ja kurssiolio kurssille ilmoittautuneet opiskelijat.
Olio osaa vastaanottaa viestejä ("käskyjä", "pyyntöjä") sen mukaisesti, millaiset metodit sille on määritelty. Esimerkiksi kurssioliota voi komentaa kirjaamaan opiskelijan ilmoittautuneeksi, auto-oliota tankkaamaan itsensä tai tiedosto-oliota poistamaan edustamansa datan kiintolevyltä. Olio ei osaa vastaanottaa sellaista viestiä, jota vastaavaa metodia sillä ei ole.
Kullakin oliolla on käyttäytymismalli, joka määrää, miten olio reagoi vastaanottamiinsa viesteihin. Käyttäytymismallin määrittelee ohjelmoija hyödyntäen ohjelmointikielen tarjoamia mahdollisuuksia. Olion voi määritellä esimerkiksi suorittamaan laskutoimituksia, kirjaamaan tietoja muistiin, lähettämään viestejä muille olioille, tai luomaan uusia olioita.
Olio on ehdottoman kuuliainen ja noudattaa ohjelmoijan sille antamia ohjeita pilkulleen. Olio-ohjelmointi(kin) vaatii siis huolellisuutta, täsmällisyyttä ja yksiselitteistä kieltä.
Olioiden välinen viestintä
Yksi olio ei paljoon pysty, mutta hallitussa yhteistyössä oliot saavat aikaan paljonkin. Tarkastellaan kahta esimerkkiä.
GoodStuff-esimerkki
Miten luvun 1.2 GoodStuff-sovellus kokonaisuutena toimii, kun sitä käytetään GUIsta käsin? Esimerkiksi: Mitä tapahtuu, kun käyttäjä painaa Add experience-nappulaa? Silloinhan pitäisi saada lisättyä tietynlainen kokemusmerkintä ja tarvittaessa päivitettyä suosikkiustietoa.
GoodStuff-ohjelman oliot hyödyntävät toistensa metodeita eli "komentavat toisiaan". Ohjelman suoritus muodostuu olioiden välisestä viestinnästä ja viesteihin reagoinnista. Seuraava esitys antaa yleiskuvan siitä, miten ohjelma toimii eräässä esimerkkitilanteessa. Vaikka esitys on graafinen, se vastaa pitkälti GoodStuff-ohjelman todellista teknistä toteutusta.
Olioiden välinen viestintä kuvattiin yllä puhekuplina, mutta puhekuplien viestit voi ilmaista myös Scala-kielen käskyinä. Vaikka nämä käskyt eivät vielä tuttuja olekaan, niin voit jo halutessasi tutkia seuraavia Scala-koodinpätkiä ja arvailla, mihin äskeisen esimerkin vaiheisiin ne liittyvät.
Experience(name, description, price, rating)
this.experiences += newExperience
newExperience.chooseBetter(this.fave)
if this.isBetterThan(another) then this else another
this.favorite = newExperience
category.addExperience(newExperience)
Kaikki mainitut käskyt tulevat tutummiksi kurssin edetessä.
Kurssi-ilmoittautumisesimerkki
Seuraava esimerkki on pääpiirteissään samanlainen kuin edellinenkin. Siihenkin kannattaa silti tutustua ymmärryksen vahvistamiseksi. Voit ohittaa esimerkin, jos on armoton kiire tai jos kaikki tuntuu täysin selvältä. Laiskuuden vuoksi ohittaminen on sen sijaan kielletty.
Ajatellaan kuvitteellista sovellusohjelmaa. Opiskelija voi ilmoittautua kursseille painamalla ohjelman käyttöliittymässä kyseiseen kurssiin liittyvää nappia. Tällöin ohjelman tulee selvittää, onnistuuko ilmoittautuminen. Ilmoittautuminen onnistuu, jos opetussaliin mahtuu ja jos sama opiskelija ei ole jo ennestään ilmoittautunut. Ilmoittautumisen onnistuessa täytyy kirjata sekä opiskelija kurssin opiskelijaluetteloon että kyseinen kurssi opiskelijan omiin kursseihin.
Luonnos yhdestä olioita käyttävästä ratkaisusta on kuvattu alla:
Olio-ohjelman tila
Olio-ohjelman kaikkien olioiden tilat muodostavat yhdessä koko ohjelman tilan. GoodStuff-sovelluksessa ohjelman tilaan sisältyvät kategoriaolion tila (nimi, suosikki ja tieto siitä, mitkä kokemukset on kirjattu) sekä kunkin kokemusolion tiedot (kuvaukset, arvosanat ja hinnat).
Olioiden toimiessa saamiensa käskyjen mukaisesti niiden tilat voivat muuttua ja samalla koko ohjelman tila. Esimerkkejä: lisätään uusi kokemus päiväkirjaan, lisätään opiskelija ilmoittautuneeksi jollekin kurssille, vaihdetaan käyttäjän henkilötietoja jne.
Olio-ohjelman suorittaminen
Olio-ohjelman olioiden muodostama käsitteellinen malli jäsentää ohjelman ihmisen kannalta järkeväksi kokonaisuudeksi. Jokaisella oliolla on tässä mallissa oma vastuualueensa, jota se hoitaa ohjelmaa ajettaessa. Pohjimmiltaan ohjelma-ajo on silti vain sarja peräkkäisiä komentoja, joita tietokone suorittaa. Ohjelmoija määrittelee käskyt olioiden yhteyteen metodeiksi. Osa metodeista saa oliot komentamaan toisiaan: olio ikään kuin siirtää toimintavuoron komentamalleen oliolle ja jää odottamaan; vain yksi olio kerrallaan on aktiivinen.
Olioiden metodit toteuttavat ohjelman osa-algoritmeja. Niitä yhdistelemällä saadaan aikaan kokonainen algoritmi, joka suorittaa ohjelmalta vaaditut tehtävät.
Olioiden välisistä viesteistä tarkemmin
Viimeistään tämän kappaleen aikana alkaa varmaan tämäkin luku kuulostaa kovin tutulta.
Metodin kutsuminen
Oliolle lähetetyt viestit aktivoivat olion metodeita. Tällaisen viestin lähettämistä sanotaan metodin kutsumiseksi (method call, method invocation). Tässä kutsutaan auto-olion "aja"-nimistä metodia:
Jotkin metodikutsut yksinkertaisesti pyytävät oliota kertomaan tietyn tilatiedon, kuten bensan määrän tankissa. Toiset tekevät jotakin monimutkaisempaa.
Viestin lisätiedot eli parametrit
Metodiparametreilla voi välittää oliolle lisätietoja siitä, mitä olion tulisi tehdä. Tässä tankattavan bensan määrä välitetään parametriksi (mikä on korostettu keltaisella):
Parametreiksi voi antaa erilaisia arvoja: lukuja, viittauksia toisiin olioihin ja niin edelleen.
Parametreja voi olla yksi tai useampia. Ja voi niitä olla nollakin, kun viesti itsessään kertoo kaiken oleellisen kuten tässä:
Vastausviestit eli paluuarvot
Monesti olio vastaa metodikutsuun jollain tapaa eli lähettää kutsujalle jotakin vastausviestinä. Sanotaan, että metodi palauttaa arvon. Metodin paluuarvo voi olla esimerkiksi tieto toiminnon onnistumisesta tai epäonnistumisesta:
Paluuarvo voi myös olla tilannetieto olion tilasta:
Pikkutehtävä olioista ja metodeista
Metodit ovat olioihin liitettyjä funktioita
Tässä luvussa on puhuttu kutsumisesta, parametreista ja paluuarvoista. Nuo metodeihin liittyvät termit ovat ihan ne samat, jotka jo kohtasit viime kierroksella funktioista puhuttaessa. Se ei toki ole sattumaa: metodit ovat funktioita, jotka on määritelty olioiden yhteyteen. Näillä olioiden funktioilla on pääsy olion tietoihin, ja ne hoitavat olion vastuualueelle kuuluvia asioita. Ne määrittelevät, mitä olio osaa tehdä.
Olioiden välinen viestintä toteutuu niin, että tietyn olion funktion (metodin) ohjelmakoodista kutsutaan toiseen olioon liitettyä funktiota.
Vaikka voitaisiin tietysti puhua "olioiden funktioista", on "metodi"-termi vakiintunut. Tälläkin kurssilla olioiden funktioita kutsutaan yleensä metodeiksi.
Voimme sijoittaa olio-ohjelmoinnin peruskäsitteet kaavioomme:
Oliot ja Scala
Scala-kieli tarjoaa työkalut yksittäisolioiden (singleton object) määrittelemiseen: voimme kirjoittaa ohjelmakoodia, joka määrittelee, mitä piirteitä yhdellä tietyllä oliolla on. Kun olio metodeineen on määritelty, sitä voi komentaa Scala-käskyillä.
Seuraavaksi opettelet olio-ohjelmoinnin perusteita koekäyttämällä valmiiksi määriteltyjä yksittäisolioita ja niiden metodeita. Myöhemmin pääset määrittelemään uusia olioita ja metodeita itse seuraavassa luvussa. Draaman kaari on siis samanlainen kuin luvuissa 1.6–1.8, joissa ensin koekäytit valmiiksi määriteltyjä funktioita ennen kuin siirryit itse toteuttamaan omia.
Jotta saamme oliota komennettua, meidän pitää pystyä ilmoittamaan tietokoneelle se, mille oliolle haluamme viestin lähettää, sekä se, mitä tuon olion metodeista haluamme kutsua. Seuraavassa esimerkissä tehdään näin ja koekäytetään erästä oliota.
Papukaijajohdanto
Esimerkkinämme toimikoon "virtuaalipapukaija". Papukaijaoliolla on tietty repertuaari
lauseita (merkkijonoja), jotka se on oppinut sanomaan ja joita se laukoo "kuullessaan"
tuttuja sanoja. Papukaijaa komennetaan puhumaan kutsumalla sen vastaa
-nimistä metodia,
jolle annetaan papukaijan kuulema lause parametriksi:
Virtuaalipapukaijamme on määritelty Oliointro-moduulissa. Ennen kuin lähdemme kutsumaan sen metodeita, nouda Oliointro kurssiprojektiisi IntelliJ’ssä ja käynnistä REPL tuohon moduuliin.
Metodikutsu Scalalla
Kutsutaan papukaijan vastaa
-metodia ja annetaan parametriksi eräs merkkijono:
papukaija.vastaa("Maistuisiko keksi?")res0: String = Polly tahtoo keksin!
Kohdeolion perään tulee piste.
Loput metodikutsusta on tuttua: metodin nimi, sitten
kaarisulkeisiin parametrilauseke tai lausekkeet aivan kuin
jo kohtaamillemme funktioille. (Muista: metodit ovat olioihin
liitettyjä funktioita.) Tässä parametriksi vastaa
-metodille
annetaan jokin merkkijono, jonka papukaija "kuulee" ja johon se
vastaa.
Metodin paluuarvona saadaan papukaijaolion omalla sisäisellä logiikallaan valitsema merkkijono.
Tässä vielä neljä esimerkkiä papukaijaolion vastaa
-metodin kutsumisesta. Kukin
käskyistä antaa parametriksi eri merkkijonon:
papukaija.vastaa("Maistuisiko keksi?")res1: String = Polly tahtoo keksin! papukaija.vastaa("Onko nimesi siis Polly?")res2: String = Polly tahtoo keksin! papukaija.vastaa("Mitä kuuluu?")res3: String = Mitä! papukaija.vastaa("Terve vaan sitten.")res4: String = Terve!
Tärkeintä tässä esimerkissämme on, että näet, miten oliota — joka sattuu nyt olemaan eräänlainen papukaijaolio — komennetaan. Se, millä perusteella tämä papukaijaolio on määritelty vastauksensa valitsemaan, ei sinänsä ole tärkeää, mutta jos tiedät siitä tämän verran, sujuu esimerkin seuraaminen paremmin:
Kun papukaija kuulee sanan, joka muistuttaa sen tuntemassa lauseessa esiintyvää sanaa, se vastaa toistamalla tuon lauseen. Tämän papukaijan repertuaariin kuuluu lause "Polly tahtoo keksin", jossa esiintyvät sekä "keksi" että "Polly". Papukaija tunnistaa sanan, jos sanan Levenštein-etäisyys (luku 1.6) tutun lauseen sanasta on korkeintaan yksi; esimerkiksi sanojen "keksi" ja "keksin" etäisyyshän on juuri yksi.
Papukaija on määritelty käyttäytymään niin, että kun sen kuulema lausahdus ei osu sen repertuaariin, se vain toistaa ensimmäisen kuulemansa sanan.
Voit myös itse vapaasti kokeilla papukaijaolion käyttöä. Valitse REPLiä käynnistäessäsi Oliointro-moduuli.
Pikkutehtävä: kaija-analyysi
Papukaijan repertuaariin kuuluu kaksi lausetta, joista yhdeksi olemme todenneet "Polly tahtoo keksin". Kokeile metodikutsu(j)a käyttäen, mikä on toinen papukaijan osaama lause. Vinkki: mainitse sille "rommi".
Olion tila
Vielä äskeisen esimerkin perusteella voisi ajatella, että olio on vain joukko funktioita, joihin pääsee käsiksi tietyn nimen kautta. Olio ei kuitenkaan ole vain sitä.
Luvun alun esimerkeistä kävi jo ilmi, että oliolla on omat tiedot, jotka muodostavat sen tilan. Olio käyttää tilatietojaan apuna: tilalla voi olla merkitystä siihen, mitä tapahtuu olion reagoidessa metodiensa kutsumiseen. Jotkin tiedot voivat olla muuttumattomia (esim. auto-olion merkki), ja monien olioiden tila ei koskaan muutu miltään osin. Kuitenkin osalla olioista on metodeita, jotka vaikuttavat olion tilaan (esim. auto-olion sijaintiin ja bensamäärään; pankkitiliolion saldoon).
Papukaijallammekin on metodi, joka vaikuttaa sen tilaan kasvattamalla papukaijan repertuaaria:
papukaija.vastaa("Hei mä tykkään susta tosi paljon")res5: String = Hei! papukaija.opiLause("Jaa, minä tykkään, että sinä olet yksi styränki")papukaija.vastaa("Hei mä tykkään susta tosi paljon")res6: String = Jaa, minä tykkään, että sinä olet yksi styränki!
Aluksi papukaija ei osaa tämän lauseen sanoja vaan toistaa vain lauseen ensimmäisen sanan.
Virtuaalipapukaijamme on hanakka oppimaan: riittää, kun kutsumme
sen opiLause
-metodia ja annamme parametriarvoksi uuden virkkeen.
opiLause
ei palauta kuin Unit
in, eikä mitään paluuarvoa
siis tulostu REPLiin.
Uusi vastaa
-kutsu todentaa oppimisen: nyt papukaija tunnistaa
tutun sanan ja toistaa repertuaariinsa lisäämänsä lauseen, jossa
tuo sana esiintyy. Oliolla on muisti!
Toinen olioesimerkki: radio
Seuraavassa esimerkissä käytämme valmiiksi määriteltyä radio-oliota. Jälleen kerran voit itse kokeilla mukana alla esitettyjä käskyjä ja varioida niitä oman makusi mukaan.
Radio-oliomme mallintaa radion kanavavalitsinta kuvitteellisessa yksinkertaistetussa
laitteessa. Sillä on neljä "pikavalintaa", joilla sen voi (virtuaalisesti) kääntää
tietylle kanavalle. Tämä onnistuu valitse
-metodilla, jolle annetaan parametriksi
pikavalinnan numero 1:n ja 4:n väliltä. Otetaan vaikkapa pikavalinta numero kaksi:
radio.valitse(2)res7: String = 94,0 MHz: Radio Suomi
Radio-olio on nyt satuttu määrittelemään niin, että pikavalinta 2 asettaa taajuudeksi 94,0
megahertsiä. valitse
-metodin paluuarvo on merkkijono, joka kertoo taajuuden ja sillä
soivan kanavan nimen. Muilla parametriarvoilla saadaan muita taajuuksia:
radio.valitse(4)res8: String = 98,5 MHz: Radio Helsinki
virita
-metodi "kääntää hertsinapista" eli muuttaa valittua taajuutta parametriksi
annetun verran nykyisestä:
radio.virita(2)res9: String = 98,7 MHz: kohinaa
Muutos mitataan "pykälissä". Tällä radiolla yksi pykälä on 100 kHz, joten tässä kasvatettiin taajuutta 2 * 100 kHz aiemmasta. (Sieltä ei löydy kanavaa.)
Huomaa, että radio-olio kykenee pitämään kirjaa omasta taajuudestaan: se määrittää itselleen uuden tilan vanhan tilansa ja saamansa parametriarvon perusteella. Tälläkin oliolla on muisti.
Tietojen kysyminen oliolta
Radio-olioltamme voi pyytää tiettyjä tilatietoja yksinkertaisesti laittamalla pisteen perään tuon ominaisuuden nimen. Voimme kysyä valitun taajuuden ja "pykälän" koon (kilohertseinä):
radio.taajuusKHzres10: Int = 98700 radio.pykalaKHzres11: Int = 100
Nämä kohdat eroavat yllä tehdyistä metodikutsuista sikäli, että näissä ei käytetty parametreja eikä kaarisulkeita.
Olion ominaisuuden muuttaminen sijoittamalla
Radio-oliomme on laadittu niin, että sitä voi komentaa muuttamaan tiettyjä ominaisuuksiaan
tutunnäköisellä sijoituskäskyllä. virita
- ja valitse
-metodeille vaihtoehtoisesti
radio-olion viritystaajuuden voi asettaa haluamakseen myös suoralla käskyllä:
radio.taajuusKHz = 92200radio.taajuusKHz: Int = 92200
Tämä on käytännössä hieman toisennäköinen tapa lähettää oliolle viesti: "Aseta
taajuusKHz
-ominaisuutesi arvoksi 92200."
Animaatio olion käyttämisestä
Olioista ja abstraktioista
Luvun 1.6 lopussa todettiin, että funktiot ja muuttujat ovat ohjelmoinnissa käytettyjä abstraktioita, jotka tekevät ohjelmoinnista käytännöllisempää.
Abstrahointi liittyy olioihin ensisijaisesti kahdella tavalla.
Ensinnäkin kukin olio on abstraktio jostakin mallinnettavasta asiasta. Siihen on valittu tiettyjä piirteitä, jotka ovat laadittavan ohjelman kannalta oleellisia, ja jätetty toisia piirteitä pois.
Toisaalta oliolla itsellään on sekä sisäinen toteutus että "julkisivu", jota käyttäen olion kanssa viestitään. Julkisivu on abstraktio itse oliosta. Siihen kuuluvat muun muassa metodien nimet, parametrien tyypit, paluuarvojen tyypit ja muutenkin kaikki se tieto, mitä olion käyttäjä tarvitsee viestiäkseen onnistuneesti olion kanssa. Metodien toteutusalgoritmit ja olion sisäisen kirjanpidon yksityiskohdat taas eivät kuulu julkisivuun. Tähän aiheeseen palaamme luvussa 3.2.
Lopuksi: olioista ja ohjelman olomuodoista
Koska tämän luvun aihe on niin keskeinen, malta katsoa vielä seuraavakin lyhyt esitys, joka käsittelee aihetta toisesta perspektiivistä ja pohjustaa tulevia lukuja.
Tässä luvussa olet nähnyt esimerkkejä Scala-olioista ja tiedät suunnilleen, miten voit käsitellä ja komentaa oliota, jonka "julkisivun" tunnet. Sotasuunnitelma on tämä:
Luvussa 2.2 opit toteuttamaan yksittäisolioita: selviää, miten voit itse määritellä uudenlaisen olion ja tavan, jolla oliosi reagoi vastaanottamiinsa komentoihin.
Luvussa 2.3 tutustut luokkiin eli olioiden tyyppeihin. Niiden avulla voi määritellä ominaisuuksia lukuisille samankaltaisille olioille kerralla. Opit aluksi käyttämään valmiiksi määriteltyjä luokkia Scalalla, ja sitten...
... luvussa 2.4 näet, miten uusia luokkia voi toteuttaa itse ja pääset jo harjoittelemaankin luokkien laatimista.
Kakkos-, kolmos- ja neloskierroksilla jatkamme GoodStuff-ohjelmaan tutustumista. Opit tuntemaan luokat, jotka tuon sovelluksen toteuttavat. Rinnalla toki työstämme monia muitakin ohjelmia.
Koko loppukurssin ajan opit erilaisia käsitteitä ja tekniikoita, joita voit soveltaa, kun rakennat ohjelmia luokista ja olioista.
Yhteenvetoa
Olio-ohjelmointi tarjoaa erään tavan määritellä ohjelman ongelmakenttään liittyviä asioita ja käsitteitä sellaisessa muodossa, joka sopii koneen käsiteltäväksi.
Olio on olio-ohjelmoinnissa käytetty kuvaus yhdelle asialle. Olioin voi kuvata mitä erilaisimpia asioita.
Tyypillisellä oliolla on sekä ominaisuuksia, jotka ovat osa sen tilaa, että toimintoja eli metodeita, jotka määräävät, mitä oliolla voi tehdä.
Kun tietokone suorittaa olio-ohjelmaa, olioiden tiedot pidetään tallessa koneen muistissa. Niistä muodostuu ohjelman tila.
Oliota voi komentaa kutsumalla sen metodeita. Metodit ovat olioihin liitettyjä funktioita, joilla käsitellään olioon liittyviä tietoja ja muutenkin hoidetaan olion vastuualueelle kuuluvia asioita.
Olio-ohjelman suorituksen päävaiheet muodostuvat olioiden välisestä viestinnästä.
Oliot voi määritellä "komentamaan" toisiaan. Ne viestivät kutsumalla toistensa metodeita. Olio voi delegoida osan tehtävästä toiselle oliolle.
Pohjimmiltaan olio-ohjelmankin ajo on tietokoneen suorittama käskysarja. Käsitteellinen mallinnus olioina jäsentää ongelmakentän; olioiden välinen viestintä määrää, missä järjestyksessä ohjelmakoodi suoritetaan.
Scalan metodikutsut toimivat kuin muutkin funktiokutsut:
Eteen kohdeolion osoittava lauseke ja piste:
olio.metodi(parametrit)
Joillakin olioilla on ominaisuuksia, joita voi muuttaa myös sijoituskäskyillä:
olio.ominaisuus = uusiArvo
.
Lukuun liittyviä termejä sanastosivulla: olio-ohjelmointi, olio, metodi; abstraktio; aihealue eli domain; tila; staattinen, dynaaminen; yksittäisolio.
Palaute
Huomaathan, että tämä on henkilökohtainen osio! Vaikka olisit tehnyt lukuun liittyvät tehtävät parin kanssa, täytä palautelomake itse.
Tekijät
Tämän oppimateriaalin kehitystyössä on käytetty apuna tuhansilta opiskelijoilta kerättyä palautetta. Kiitos!
Materiaalin luvut tehtävineen ja viikkokoosteineen on laatinut Juha Sorva.
Liitesivut (sanasto, Scala-kooste, usein kysytyt kysymykset jne.) on kirjoittanut Juha Sorva sikäli kuin sivulla ei ole toisin mainittu.
Tehtävien automaattisen arvioinnin ovat toteuttaneet: (aakkosjärjestyksessä) Riku Autio, Nikolas Drosdek, Kaisa Ek, Joonatan Honkamaa, Antti Immonen, Jaakko Kantojärvi, Niklas Kröger, Kalle Laitinen, Teemu Lehtinen, Mikael Lenander, Ilona Ma, Jaakko Nakaza, Strasdosky Otewa, Timi Seppälä, Teemu Sirkiä, Anna Valldeoriola Cardó ja Aleksi Vartiainen.
Lukujen alkuja koristavat kuvat ja muut vastaavat kuvituskuvat on piirtänyt Christina Lassheikki.
Yksityiskohtaiset animaatiot Scala-ohjelmien suorituksen vaiheista suunnittelivat Juha Sorva ja Teemu Sirkiä. Teemu Sirkiä ja Riku Autio toteuttivat ne apunaan Teemun aiemmin rakentamat työkalut Jsvee ja Kelmu.
Muut diagrammit ja materiaaliin upotetut vuorovaikutteiset esitykset laati Juha Sorva.
O1Library-ohjelmakirjaston ovat kehittäneet Aleksi Lukkarinen ja Juha Sorva. Useat sen keskeisistä osista tukeutuvat Aleksin SMCL-kirjastoon.
Tapa, jolla käytämme O1Libraryn työkaluja (kuten Pic
) yksinkertaiseen graafiseen
ohjelmointiin, on saanut vaikutteita tekijöiden Flatt, Felleisen, Findler ja Krishnamurthi
oppikirjasta How to Design Programs sekä Stephen Blochin oppikirjasta Picturing Programs.
Oppimisalusta A+ luotiin alun perin Aallon LeTech-tutkimusryhmässä pitkälti opiskelijavoimin. Nykyään tätä avoimen lähdekoodin projektia kehittää Tietotekniikan laitoksen opetusteknologiatiimi ja tarjoaa palveluna laitoksen IT-tuki. Pääkehittäjänä on nyt Markku Riekkinen, jonka lisäksi A+:aa ovat kehittäneet kymmenet Aallon opiskelijat ja muut.
A+ Courses -lisäosa, joka tukee A+:aa ja O1-kurssia IntelliJ-ohjelmointiympäristössä, on toinen avoin projekti. Sen suunnitteluun ja toteutukseen on osallistunut useita opiskelijoita yhteistyössä O1-kurssin opettajien kanssa.
Kurssin tämänhetkinen henkilökunta löytyy luvusta 1.1.
Joidenkin lukujen lopuissa on lukukohtaisia lisäyksiä tähän tekijäluetteloon.
Metodikutsu aloitetaan ilmoittamalla viestin vastaanottaja eli kohdeolio. Tämä käy kirjoittamalla lauseke, jonka arvo on viittaus johonkin olioon. Kurssin tarjoamassa valmiissa pakkauksessa on määritelty, että nimi
papukaija
viittaa yksittäiseen papukaijaolioon.