Ilkka Koivistoinen 13.02.2002

Edellinen

Seuraava

8. Olio-ohjelmointi

Objekti orientoituneella ohjelmoinnilla (OOP - object oriented programming) eli olio-ohjelmonnilla pyritään laistamaan ne sudenkuopat, joita perinteinen proseduraalinen ohjelmointi on aiheuttanut. Vaikka olio-ohjelmointi on varsin hankala aloittaa, on sen käyttö ohjelmakoodin määrän kasvaessa kannattavaa. Kun perinteisessä proseduraalisessa ohjelmointitavassa kirjoitat ohjelman, et voi tietää kaikkia mahdollisia tapoja sen käyttöön ja kun haluat melkein samalaisen ohjelman kirjoitat sen yleensä käytännössä uudestaan. Olio-ohjelmonnissa käytät kirjoittamaasi koodia yhä uudelleen ja uudelleen.

Perinteisessä ohjelmointitavassa tieto eli data ja sitä käsittelevä proseduuri eli metodi eivät välttämättä ole aina oikein suhteessa toisiinsa. Tämä aiheuttaa proseduurin epävarman toiminnan. Se saattaa reagoida väärin, koska proseduurin ohjelmoija ei ole osannut ottaa huomioon sellaista käyttöä, mihin sitä myöhemmin käytetään.

Olio-ohjelmonnissa data ja sitä käyttävät metodit paketoidaan yhteen. Luotaessa olio määrätään samalla sen sisältämä data ja miten tätä dataa voidaan käyttää.wpeD.jpg (9170 bytes)

 

 

Perinteisessä tavassa data ja sitä työstävä metodi on eritelty toisistaan. Oheisen kuvan nuija (metodi) on tarkoitettu kokouksien pitoon, mutta huolimaton käyttäjä haluaa tehdä sillä omelettia

 

 

wpeE.jpg (30849 bytes)

 

 

Nyt olio on muodostettu siten, että nuija voi käsitellä vain päätöksiä §1, §2 ja §3. Muullaisen tiedon (munien) nuijiminen ei ole mahdollista

 

 

 

 

Oliohjelmointi ruokkii itseään. Olioita voidaan käyttää yhä uudestaan ja uudestaan. Jos yhden olion ominaisuudet loppuvat, voidaan sen avulla luoda uusi olio, joka perii kaikki ne ominaisuudet, jotka olivat sillä oliolla, josta se luotiin (esi-isä). Uudelle  oliolle (jälkeläinen) voidaan lisätä kaikkien esi-isän ominaisuuksien lisäksi uusia ominaisuuksia. Nämä voidaan periyttää jälleen uudelle jälkeläiselle ja niin edelleen.

Javassa jokaisella jälkeläisellä on vain yksi esi-isä (yksinkertainen perintä). Joissain muissa oliokielissä (esim. C++) voidaan jälkeläisellä olla useamman eri esi-isän ominaisuuksia (moniperintä)

Javassa olioista puhuttaessa kutsutaan niitä luokiksi.

Olkoot meillä luokka (eli siis olio) puu. Sillä olkoot ominaisuudet kasvaa ja varjostaa. Tiedämme hyvin, että ihan oikeilla puilla on nimenomaan nämä ominaisuudet. Kirjoitamme siis luokkaan puu kaksi metodia.

Oliot4.gif (6046 bytes)kasvaa(); varjostaa();

Metodin perään laitetaan aina sulut, jotta se erotettaisiin muuttujista. Tiedämme myös, että on olemassa erilaisia puutyyppejä - pensas, havuPuu, lehtiPuu, palmu (Kuvissa olevat nimet on hieman erilailla nimetty. Kuvien nimet on siis väärin kirjoitettu)

wpe10.jpg (26811 bytes)

Luokka pensas periytetään luokasta puu. Täten pensas kasvaa() ja varjostaa(). Lisäksi sillä on ominaisuus tuottaaMarjoja();

Myös luokka havuPuu perityy luokasta puu. Täten sekin kasvaa() ja varjostaa(). Lisäksi sillä on ominaisuus majoitaOrava(); havuPuu ei tiedä mitään ominaisuudesta tuottaaMarjoja().

Luokka palmu periytyy sekin luokasta puu ja sillä on ominaisuudet kasvaa() ja varjostaa(). Tunnetusti palmut huojuvat, joten kirjoitetaan sille ominaisuus huojuu();

Luokka lehtiPuu periytyy sekin luokasta puu ja silläkin on ominaisuudet kasvaa() ja varjostaa(). Sille laitamme lisäominaisuudet pudotaLehdet() ja kasvataUudetLehdet().

Nyt olemmekin valmiit metsänhoitajiksi. Kuitenkin unohdimme (Näinhän aina käy. Tässä koko olio-ohjelmoinnin juju onkin) sen, että puita pitää myös metsänhoidollisista syistä kaataa. Niinpä teemme uuden esi-isän (eli kantaluokan eli superluokan) josta luokka puu periytyy. Olkoot sen nimi hyötypuu (Käytetään tässä skandimerkkejä, vaikka yritänkin niitä muuttujanimissä systemaattisesti välttää)

wpe17.jpg (3539 bytes)wpe10.jpg (26811 bytes)

Laitetaan sille ominaisuus kaato(); Suunnitteluvaiheessa uuden superluokan tekeminen vielä onnistuu, mutta ei enää myöhemmin. Sellaisen ominaisuuden kuin kaato lisääminen kaikkiin luokkiin pensas, havuPuu, lehtiPuu, palmu jälkikäteen olisi ollut hankalaa. Kuitenkin niin olisi ollut pakko tehdä, jos kantaluokka olisi ollut jo olemassa, testattu ja paketoitu.

Nyt aloitetaan. Luodaan luokan havuPuu instanssi (jota javassa sanotaan olioksi) mänty1. Tällä tarkoitetaan, että otetaan käyttöön olio mänty1, jolla on ne ominaisuudet, mitä luokka havuPuu on kaikkien periytymisien kautta saanut (siis kaato(), kasvaa(), varjostaa() ja majoitaOrava(); Tehdään vastaavasti instanssit mänty2, mänty3, mänty4 ja mänty5. Metsämme näyttää nyt seuraavalta.

wpe18.jpg (14321 bytes)Jos nyt kirjoitamme mänty3.kaato(); ja mänty4.kasvaa(); saamme metsästämme seuraavanlaisen            wpe19.jpg (15539 bytes)

Lisäämme puita. Muodostamme pensas luokan oliot tyrni1, tyrni2 ja tyrni3 sekä lehtiPuu luokan oliot hk1, hk2 (hk niin kuin hevoskastanja). (Palmuja emme kasvata näin kaukana aurinkorannoista.) Metsämme on siis nyt seuraava:

wpe1A.jpg (32781 bytes)

Nyt hoidamme metsää. Tehdään tyrni1.kasvaa(), hk1.pudotaLehdet(), hk2.varjostaa() ja tyrni2.tuotaMarjoja(). Ja johan onkin metsässä käynyt kuhina, kuten seuraavasta kuvasta näkyy (tyrnin 2 marjat hieman huonosti)

wpe1B.jpg (34569 bytes)

(Koska tämä ei ole luonnotieteen opus, emme odota seuraava kevättä kirjoittamalla hk1.kasvataLehdet()). Oravat ovat myös katsoneet parhaaksi siirtyä muualle, joten emme myöskään voi kirjoitaa esim mänty5.majoitaOrava().

Oravat eivät muuten asu luonnossa palmuissa. Ohjelmammekaan ei voi tehdä luokan palmu oliolle Kookospalmu komentoa Kookospalmu.majoitaOrava(), sillä palmu luokka ei tunne metodia majoitaOrava. Proseduraalisessa ohjelmassa tämä olisi hyvin onnistuttu tekemään ( ja samalla luomaan vahingossa kokonaan uusi oravapopulaatio etelämeren aurinkorannalle :-)  .)

Tehtävien nimeämisessä joudutaan nyt tekemään pieni muutos. Laita harjoitustehtävien luokkien nimiksi se, mitä tehtävässä pyydetään. Tämä pakottaa nimeämään talletustiedostot samalla nimellä.

 

Yhteenveto

Ihmiselle ominainen abstrakti käsite kirjoitetaan javassa luokaksi. Mitä käsitteelle tehdään, kirjotetaan luokan metodiksi. Kaikki tieto, joka käsitteeseen liittyy kirjoitetaan luokan dataksi.
Luokka (esi-isä) voidaan periyttää aliluokaksi (jälkeläinen), jolle voidaan kirjoittaa uusia metodeja sekä dataa. Aliluokalla on kaikki ne ominaisuudet, joita myös sen esi-isällä eli kantaluokalla eli superluokalla oli.
Luokka saadaan käyttöön luomalla luokan instanssi eli olio. Kunkin olion ominaisuudet ja data eivät mene sekaisin muiden olioiden ominaisuuksien tai datan kanssa. Olion luokan dataan viitataan vain luokan metodien avulla (ei siis suoraan, vaikka java sen salliikin).

Ilkka Koivistoinen 13.02.2002

Edellinen

Seuraava