TEHTÄVÄNANTO: 3. "Mitä ihmettä nuo parametrit oikein ovat ja miten int-arvo ja PikkuVarasto-olio eroavat toisistaan parametreina?", kysyy ystäväsi kuunnellessaan tarinoitasi Ohjelmoinnin perusteet -kurssilta. Ystäväsi on ohjelmoinut sen verran, että hän tuntee yksinkertaiset muuttujat, lausekkeet ja lauseet. Hän on ymmärtänyt myös metodin kutsumisen idean, mutta parametrien kohdalla tie tuntuu nousseen pystyyn. Auta ystävääsi ymmärtämään, mistä parametrien käyttämisessä on oikein kysymys, mitä hyötyä ja iloa niistä on. Laadi siis asiasta kirjallinen selitys (enimmäispituus 1 arkki). Muista että esimerkit auttavat oppimisessa. Vastauksen arvioinnissa otetaan huomioon selostuksen ajateltu lukija. Älä siis kirjoita tarkastajalle, joka jo tuntee asian, kirjoita tuolle ystävälle! ------------------------------------------------------------------- MALLIVASTAUKSEN TAPAISTA: (Ei tietenkään ole edellytetty suoraa sitaattia kurssimateriaalista, oikeasti. Eikä ollenkaan näin pitkää selostusta - tehtävässähän oli pituusrajakin. Tämä on tässä enemmän opin vuoksi.) Kurssimateriaalista: "Metodille voidaan antaa lähtötietoja ns. parametrien avulla. Parametrit ovat metodin määrittelyssä - nimen jälkeen sulkeissa - määriteltyjä muuttujia. Ne saavat alkuarvokseen metodin kutsussa annettavat arvot, ns. todelliset parametrit, ennen metodin algoritmin suorituksen aloittamista. Metodin määrittelyssä olevia parametreja sanotaan joskus 'muodollisiksi parametreiksi', koska ne metodissa tavallaan edustavat milloin mitäkin todellisia parametreja." Toisin sanoen, jos metodin määrittely on esimerkiksi private static void metodi(int i, Olio o) { } niin kun metodia kutsutaan, syntyvät ensin paikalliset muuttujat i ja o. Niiden arvoiksi annetaan kutsussa määritellyt arvot. Esimerkiksi jos kutsuvassa metodissa sanotaan int k = 5; Olio jussi = new Olio(); metodi(k, jussi); tulee metodin paikallisten muuttujien arvoiksi seuraavat: i:n arvoksi viisi ja o:n arvoksi viite samaan olioon kuin mihin jussi-muuttujasta on viite. Parametreista on se hyöty, että niiden avulla saat metodisi tekemään periaatteessa saman asian, mutta vähän eri tavoilla kun kutsut sitä eri parametrien arvoilla. Oletetaanpa, että sinulla vaikka on olio, jonka yksityiselle muuttujalle int foo voidaan asettaa arvoja yhdestä kymmeneen. Jos parametreja ei olisi, joutuisit ohjelmoimaan kymmenen metodia: void asetaFooYkkoseksi() { this.foo = 1; } void asetaFooKakkoseksi() { this.foo = 2; } ja niin edelleen. Kun käytät parametreja, selviät yhdellä metodilla, esimerkiksi: void asetaFoo(int i) { if(i > 0 && i < 11) this.foo = i; } Olioparametrin ja alkeistyyppisen parametrin ero voidaan ajatella seuraavasti. Viitetyyppisen muuttujan arvo on viite toiseen olioon, alkeistyyppisen muuttujan arvo taas ko. luku tai merkki sinänsä. Kun muuttujalle asetetaan arvo, kopioidaan tuo arvo muuttujan arvoksi. Kun siis alkeistyyppisen muuttujan arvo asetetaan toisen alkeistyyppisen muuttujan arvoksi, arvo kopioidaan. Viitetyyppisen muuttujan tapauksessa taas kopioidaan ainoastaan viite ("nuoli") kyseiseen olioon, ei oliota itseään. Jos siis sinulla on metodi public static void metodi(int i, Olio o) { i = 5; olio.asetaFoo(5); } ja kutsuvassa metodissa seuraava koodinpätkä: int k = 1; Olio jussi = new Olio(); jussi.asetaFoo(1); metodi(k, jussi); System.out.println(k + " " + jussi.mikäFoo()); tulostaa koodi "1 5". Tämä johtuu siitä, että kun k:n arvo on välitetty parametrina, se on kopioitu i:hin. Kun metodi siis muuttaa oman i-muuttujansa arvoa, ei kutsujan k-muuttujan arvo muutu mihinkään. Olio-tyyppistä muuttujaa parametrina välitettäessä kopioidaan kuitenkin viite olioon, ei oliota itseään. Näin kutsujan jussi-muuttuja ja metodin o-muuttuja tulevat osoittamaan samaan olioon. Kun oliota muutetaan o-muuttujan kautta, muutos tietenkin näkyy myös jussi-muuttujan kautta. Koko ajan on olemassa siis vain yksi Olio-tyypin ilmentymä, johon viitataan kahdesta eri paikasta. Alkeistyyppistä int-arvoa on metodin suorituksen ajan olemassa kaksi täysin eriävää lukua - niille vain hetkeksi asetetaan "samannäköinen" arvo. --------------------------------------------------------------------- ARVOSTELUPERUSTEITA: yht. 12 p Parametrit ovat metodin paikallisia muuttujia... (2p) ... joille asetetaan arvo kutsuhetkellä kutsun mukaan. (2p) Selkeä esimerkki metodin kutsumisesta. (1p) Hyöty. (2p) Joko kuten mallivastauksessa tai esim. "ei tarvitse käyttää globaaleja tai vastaavia muuttujia tiedon välittämiseen metodilta toiselle" tai vastaavaa. Pelkkä "tiedon välitys metodille" 1 p. PikkuVaraston ja intin ero selitetty oikein (viitteet mainittu). (2p) Selitetty miten tämä vaikuttaa metodin ulkopuolelle (ie, muutokset olioon säilyvät). (2p) Selkeä esimerkki tästä. (1p) Erityisen selkeä tyyli tai hyvät esimerkit +1p harkinnan mukaan (kuitenkin max. 12 pistettä, tietenkin). Esimerkkien asiat on toki voinut esittää samassakin esimerkissä. Täsmällisiä määritelmiä ei ole vaadittu. Lähes kaikissa kohdissa ainakin osan pisteistä on voinut saada osoittamalla rivien välistä tajunneensa asian, vaikkei olisi osannut pukea asiaa ihan kunnolla sanoiksi - olettaen, ettei ole sanonut ihan puuta heinää yrittäessään. --------------------------------------------------------------------- Sekalaisia huomioita: - Monella kurssilaisella on erittäin hyviä ystäviä. Useassa paperissa luvattiin oikein paneutua selvittämään asiaa ja soittaa illalla uudestaan...:) - Kuormittamista ei kysytty, eikä se sinänsä liity tähän asiaan, joten sen selittämisestä ei ole saanut pisteitä, vaikka olisi selittänyt miten hyvin (moni oli). Kuormittaminen on sinänsä hyödyllinen asia, joka kyllä liittyy parametreihin, mutta se ei ole mikään parametreista automaattisesti seuraava hyöty. - On väärin sanoa "parametrin arvoa ei voida muuttaa metodin sisällä" - ainakin, jos on aikaisemmin kuvannut, että tarkoittaa parametrilla myös sitä metodin muuttujaa, eikä ainoastaan sitä arvoa, joka ulkopuolelta välitetään. Tottakai arvoa voi muuttaa. Muutos vain ei näy metodin ulkopuolella. - Moni sanoi myös, että "kun parametrina välitetään viite olioon, parametriksi annetun muuttujan arvoa voidaan muuttaa" tai vastaavaa. Huomatkaa nyt, että oliotyyppisen muuttujan arvo on viite siihen olioon. Metodista käsin *ei* voi muuttaa sitä kutsujan muuttujien arvoja, eli sitä, mihin ko. muuttujista on viite. Sen viitteen kohteena olevaa oliota voi toki muuttaa parametrimuuttujankin kautta, mutta se on eri asia kuin kutsujan muuttujien arvojen muuttaminen. - Jälleen kerran monessa paperissa esiintyi väite, että oliota ei voi muuttaa, kun se on kerran luotu. Unohtakaa moinen Javan yhteydessä. - Ei ole hyvä idea käyttää vastauksessa itselle vieraita termejä, jos ei ole varma, mitä termeillä tarkoitetaan. Nyt moni sotki hyvän asiansa siteeraamalla väärin muodollisia ja todellisia parametreja käsitteleviä lauseita kurssimateriaalista. - Lopuksi vielä erityiskiitos TM:lle tarinasta, joka oli varsin viihdyttävä. Valitettavasti kaunokirjallisista ansioista ei voi antaa lisäpisteitä. :)