Johdatus ohjelmointiin, syksy 1998, 2. välikoe 17.12.1998, tehtävä 1 Arvosteluperusteet ja esimerkkiratkaisuja (Allan Halme) Yleistä ------- - Termejä yliOHJELMA ja aliOHJELMA käytettiin, kun tilalla olisi pitänyt käyttää yli- ja aliluokka. Näiden termien käyttö näyttäisi viittaavan siihen, ettei opiskelija ole oppinut eroa luokan ja ohjelman välillä, eikä eroa yli- ja aliluokka -suhteen ja yli- ja aliohjelma -suhteen välillä. - Termit ovat yliluokka ja aliluokka, ei ylä- ja ala-. - Täytesanojen "mm" ja "jne" ja "esim" käyttö oli varsin ikävää. Usein sillä oli yritetty täydentää paperille puuttuvaa osaamista, mutta ei se auta. Välttäkää näiden käyttöä, tai käyttäkää varovasti. Lyhyydestä ---------- Viittä peruskäsitettä pyydettiin selostamaan lyhyesti ja täsmällisesti. Käytännössä yli kolmestasadasta tenttivastauksesta vain muutama oli lyhyt, joskin suurin osa oli melko täsmällisiä. Aivan liikaa oli puolen sivun esseevastauksia, puhumattakaan yhden tai useamman sivun sepustuksista. Lyhyt vastaus tarkoittaa että kuvaa asian olennaisen ytimen ja jättää muut sivuvaikutusten ja oheishuomautusten selitykset sikseen. Esimerkiksi lainaan erästä vastausta: kuormittaminen - Metodin voi "kuormittaa" käyttämällä samaanimeä eri metodeissa, joilla on erityyppiset ja/tai -määräiset parametrit. [Tähän kelpo vastaus, tämä on vielä lyhyt. Seuraava jatko on turhaa:] Täten kyseisellä nimellä kutsutun metodin valinta riippuu kutsun parametreistä. Myös pelkkää nimeä voi kuormittaa käyttämällä sitä sekä luokan nimenä, että luokan ilmentymän nimenä, kuten näimme Reuse-esimerkissä. Alkeistyyppi ------------ Alkeistyyppi on muuttujan sellainen (perus)tyyppi, että ko. muuttujan arvo on suoraan tallessa itse muuttujassa. 1p - jos osasi ilmaista että arvo on suoraan tallessa ½p - jos luetteli joitain Javan perustyyppejä - Aivan liikaa yritettiin määritellä alkeis- ja viittaustyyppejä kuvaamalla niiden vertailusemantiikkaa ("alkeistyyppejä vertaillessa vertautuu arvot, viittaustyypejä vertaillessa vertautuu, osoittavatko samaan olioon" tms). Vaikka näin tietenkin on, ei tämä ole varsinaisesti määritelmä, vaan määritelmän sivuvaikutus. - Samoin hyvinkin paljon selostettiin alkeistyyppisten muodollisten ja todellisten parametrien käyttäytymistä metodikutsuissa ... tämähän on edelleen pelkästään vain määritelmän sivuvaikutusta. - Alkeistyyppi ei ole muuttuja, vaan muuttujan tyyppi. - Alkeistyyppiä ei voi määritellä sanomalla että se on `kielen itsensä määrittelemä,' sillä kielihän määrittelee muitakin tyyppejä, nimittäin joukko valmiita luokkia, joiden ilmentymiä viittaamaan voidaan määritellä viittaustyyppisiä muuttujia. - Jotkut vastauksista kuvasivat jotain sinänsä ihan oikeata ja mielenkiintoista asiaa liittyen alkeistyypin olemukseen ja määritelmään, mutta joista kuitenkin olennaisesti puuttui juuri tuo kysytty määritelmä. - `Ei ole olio' ei ole määritelmä, vaikka se totta onkin. - Myöskään muuttujan tyypin määritelmä ei ole *alkeis*-tyypin määritelmä. Viittaustyyppi -------------- Viittaustyyppi on muuttujan sellainen tyyppi, että ko. muuttujan arvona on viittaus olioon. 1p - jos osasi tuon sanoa; muistaakseni lähes kaikki osasivat - Samoin tässäkin hyvinkin paljon selostettiin viittaustyyppisten muodollisten ja todellisten parametrien käyttäytymistä metodikutsuissa ... tämähän on todellakin vain määritelmän sivuvaikutusta. - Määritelmään *EI* kuulu, että viittaustyyppisiä muuttujia käsitellään (vain) metodien tai aksessorien kautta. Toki tämä on kaunista olio- paradigmaa kapselointeineen ja edustaa hyvää yleistä tapaa, mutta se ei kuulu viittaustyypin määritelmään. - Pelkkä lause "roikkuvat langan päässä" osoittaa lähinnä osuvan lauseen muistamista, eikä juurikaan vakuuta osaamisesta ja ymmärtämisestä; päätin kuitenkin tulkita tällaista vastaus ymmärrykseksi ja olen antanut pisteen. - Viittaustyyppejä ovat todellakin muutakin kuin "luokkien [ilmentymiä], taulukoita, ja merkkijonoja." Huomatkaa, hyvät opiskelijat, että kaikki edellämainitut ovat olioita. - Eikä viittaustyyppi ole ollenkaan sama kuin abstrakti tietotyyppi! Jälkimmäisen vaan voi toteuttaa kauniisti olioparadgimassa, ja viittaustyyppiset muuttujat ovat vain siinä käytettävä työkalu. Abstraktin tietotyypinhän voi toteuttaa ilman viittaustyyppiä (toki ei Javassa). Kuormittaminen -------------- Kuormittaminen on saman metodinimen käyttöä samassa nimiavaruudessa; metodit eroavat toisistaan otsikoistaan eli parametriensa lukumäärältään tai niiden tyypeiltään. ½p - saman nimen käyttö ½p - otsikoiden erottava, eli parametrien lukumäärä ja/tai -tyypit - Metodin näkyvyysmääreiden ja palautustyyppien eroaminen toisistaan ei kuormita. - Itse asiassahan on niin, että myös luokan nimeä voi kuormittaa, samoin voi olla samanniminen muuttuja ja muitakin tunnuksia. Tässä tehtävässä on kuitenkin haettu juuri tuota metodinnimen kuormitusta. (Materiaalista: ~wikla/JohdOhj/Sisalto/4/Nakyvyys.html: "Kielessä on mielestäni sallittu liian laaja nimien kuormittaminen") Korvaaminen ----------- Korvaamisella tarkoitetaan samannimisen metodin määrittelyä aliluokkaan kuin esiintyy aikaisemmin yliluokassa. Uudella metodilla on oltava sama otsikko (samat parametrien lukumäärät ja tyypit), mutta toteutus on vapaa. ½p - aliluokassa määritellään sama/samanniminen/samanlainen metodi kuin yliluokassa ½p - samalla otsikolla - Korvaavan toteutuksen ei välttämättä tarvitse erota korvatusta. (-0p) - Metodejan korvataan; kenttiä peitetään. (-0p) - Olennaista on että on oltava sama _otsikko_! (ei pelkästään sama nimi). Selitykseksi ei kelpaa että "aliluokka parantelee yliluokkaa" tms - Nimenomaan aliluokassa korvataan yliluokassa olevaa. - Samassa luokassa olevaa metodia ei voi korvata! Käännösyksikkö -------------- Käännösyksikkö on .java-päätteinen tiedosto, jossa määritellään luokkia, joista enintään yksi voi olla julkinen. Tiedostossa voi myös määrätä luokkaa kuulumaan johonkin pakettiin (package-määreellä); lisäksi voi tuoda samaan nimiavaruuteen muita luokkia import-määreellä. ½p - luokkia määritellään ½p - luokat voi määrätä pakettiin Tätä oli ymmärretty kaikkein huonosti ja vielä niin, että ihmisillä oli aivan kummallisia ja täysin vääriä käsityksiä, tai sitten vastauspaperiin laitettiin paljon arvauksia. Oikein vastanneiden kesken oli hyvin opeteltu Arton kolmen ranskalaisen viivan lista huomautuksineen! :) Mikä oli ihan hyvä asia, koska se on hyvä lista ja se on oikein. - Huomatkaa hyvät ihmiset seuraavat erittäin tärkeät ja monesti täysin väärin ymmärretyt asiat: - Käännettäessä .class-tiedostot syntyvät AINA nykyhakemistoon! Paketointimääre package EI sijoita syntyneitä luokkatiedostoja mihinkään muihin hakemistoihin! .class-tiedostoon vaan koodataan paketin nimi ja on käyttäjän vastuulla sijoittaa tiedosto paketin nimen mukaan sellaisen polun päähän, jonka alkuun osoitetaan CLASSPATH- ympäristömuuttujalla. - import-määre ei `anna lupaa' käyttää mitään. Kaikkea on aina lupa käyttää. import vaan luettelee paketteja ja luokkia, joista kääntäjä voi etsiskellä, kun koodissa viitataan johonkin luokkaan. Esimerkiksi jos haluaa käyttää luokkaa java.util.Vector, voi siihen viitata sen koko nimella (`java.util.Vector'), taikka voi sanoa joko `import java.util.*a', jolloin tulee kaikki util-luokat, tai voi sanoa `import java.util.Vector', jolloin tulee vain vektoriluokka, mutta näiden jälkeen voi koodissa viitata suoraan Vector-nimellä ko. luokkaan. - Oletuspakkaus on eri asia kuin nykyhakemisto! Tämä on hieman kinkkinen asia, koska tältähän se käytännössä varmaan näyttää monelle opiskelijalle. Oletuspakkaus on kuitenkin vain nimetön pakkaus, johon kuuluvia luokkia etsitään pelkästään CLASSPATH-ympäristömuuttujan suoraan osoittamista paikoista. Käännös aina tuottaa .class-tiedostot nykyhakemistoon. Ja jos ei ole `.' -hakemisto mukana CLASSPATHissä, ei java-tulkki niitä myöskään löydä. - Käännösyksikkö on olennaisesti tiedosto! .java-päätteinen tekstimuotoinen sellainen, joka sisältää Java-luokkien määrittelyjä. - Käännösyksikkö ei ole kääntäjä. - Käännösyksikkö ei ole bytecode-muotoinen eikä siten myöskään ole .class -tiedosto. Vastaavasti mikään .class -tiedosto ei ole käännösyksikkö. - Käännösyksikössä määritellyistä luokista syntyy käännettäessä jokaisesta luokasta .class-tiedosto. - `Yksi .java-tiedosto' ei ole riittävä vastaus (½p) - Ei ole mikään `pätkä' koodia. - Käännösyksikkö n se itse tiedosto, ei ne package- ja import-määreet. - Käännösyksikköön ei oikeastaan pitäisi sanoa kuuluvan metodeja eikä olennaisemmin ne on ne luokat, jotka ovat käännösyksikössä. Voihan semmonen luokka olla, jossa noita ei ole. -- Allan Halme * allan@iki.fi * iki.fi/allan --