Kurssin viimeisimmän version löydät täältä: O1: 2024
Luku 4.1: Autoiluharjoitus
Tästä sivusta:
Pääkysymyksiä: Osaanko jo kohta toteuttaa Scala-luokkia sujuvasti?
Mitä käsitellään? Yhdistellään aiempien lukujen aiheita. Lisäksi: lyhennysmerkinnät sijoituskäskyille; vähän lisää metodinimien kuormittamisesta.
Mitä tehdään? Ohjelmoidaan ja leikitään annetulla autoiluohjelmalla.
Suuntaa antava työläysarvio:? Kolme, neljä tuntia? Omatoiminen ohjelmointi voi tuottaa haasteita, joten tehtävässä on jumiutumismahdollisuus. Kannattaa varata mukavasti aikaa, lukea vinkit kunnolla ja hyödyntää kurssin neuvontapalveluita, ettei aikaa mene tolkuttomasti. Jos ei jää jumiin, voi kyllä selvitä nopeamminkin.
Pistearvo: A5 + B80.
Oheisprojektit: CarSim (uusi).
Aluksi: lyhennysmerkinnöistä
Kun sijoitamme esimerkiksi kokooja- tai askeltajamuuttujaan, käytämme uuden arvon määräävässä lausekkeessa muuttujan vanhaa arvoa. Kun kyseessä on lukuarvoinen muuttuja, uusi arvo usein määräytyy aritmeettisen laskutoimituksen tuloksena. Esimerkiksi:
this.saldo = this.saldo + maara
this.value = this.value + 1
Koska tämänkaltaiset sijoitukset ovat yleisiä ja koska niissä toistuu sama koodinpätkä useita kertoja, on määritelty lyhyempiä tapoja merkitä asia. Esimerkiksi äskeiset koodinpätkät voi kirjoittaa näinkin:
this.saldo += maara
this.value += 1
Sijoitusoperaattori +=
siis tarkoittaa: "Kasvata vasemmalla puolella mainitun muuttujan
arvoa oikealla puolella olevan lausekkeen verran." Tai tarkemmin: "Ota vasemmalla puolella
mainitun var
-muuttujan vanha arvo ja oikealla puolella olevan lausekkeen arvo. Laske ne
yhteen. Sijoita lopputulos vasemmalla puolella mainittuun muuttujaan."
(Tässä on muuten kyseessä täsmälleen samanlainen merkintä +=
kuin luvussa 1.5, jossa
merkintää käytettiin lisäämään uusi arvo puskuriin. Huomaa, että nyt on kysymys eri
asiasta eli yhteenlaskusta. Analogia tapausten välillä toki on: puskuria päivitetään
lisäämällä vs. muuttujan arvoa päivitetään lisäämällä.)
Syntaktinen sokeri
Ei ole harvinaista, että ohjelmointikieli tarjoaa erilaisia tapoja kirjoittaa saman asian. Tällöin usein puhutaan syntaktisesta sokerista (syntactic sugar) eli sellaisista kielirakenteista, jotka eivät ole ohjelmointikielen ilmaisuvoiman kannalta välttämättömiä (eli eivät mahdollista uudenlaisia ohjelmia) mutta jotka tekevät asioiden ilmaisemisesta ohjelmoijan kannalta kätevämpää tai kauniimpaa. Yllä esitellyt lyhennysmerkinnät yleisille sijoituksille ovat esimerkki syntaktisesta sokerista.
Syntaktinen sokeri on makuasia, josta voi halutessaan kiistellä. Koska lähes kaikki yleiskäyttöiset ohjelmointikielet (kuten Scala) ovat laskennalliselta ilmaisuvoimaltaan yhtä hyviä, voisi jopa sanoa, että eräällä tavalla ohjelmointikielet yleensäkin ovat vain syntaktista sokeria.
Lisää lyhennyksiä
Vastaavia lyhennysmerkintöjä on enemmänkin; esimerkkejä niistä on alla olevassa taulukossa. Scala-työkalut automaattisesti "laventavat" lyhennetyt käskyt.
Pidemmin | Lyhyemmin |
---|---|
arvo = arvo + toinen |
arvo += toinen |
arvo = arvo - toinen |
arvo -= toinen |
arvo = arvo * toinen |
arvo *= toinen |
arvo = arvo / toinen |
arvo /= toinen |
arvo = arvo % toinen |
arvo %= toinen |
Näiden lyhennysmerkintöjen käyttö on yleistä, ja käytämme niitä jatkossa myös tällä kurssilla. Voit käyttää niitä itse esimerkiksi tämän luvun ohjelmointitehtävässä tai olla käyttämättä. Joka tapauksessa on tarpeen pystyä lukemaan koodia, jossa niitä käytetään.
Usein kysytty kysymys
Eräissä yleisissä ohjelmointikielissä (esim. C, Java) on oheisiakin
lyhyempi ilmaisu, jolla lisätään tai vähennetään ykkönen muuttujan
arvosta. Esimerkiksi luku++
ja luku--
tarkoittavat samaa kuin
luku += 1
ja luku -= 1
. Onko tällaisia merkintöjä Scalassakin?
Vastaus: Ei ole, koska lisälyhennykset on katsottu tarpeettomiksi.
Usein Scalalla ohjelmoidaan tyylillä, jossa var
-muuttujia käytetään
niukasti (luku 10.2), joten näiden merkintöjenkin merkitys on
vähäisempi. Toisaalta Scalalla voi itsekin määritellä "omia
operaattoreita" (luku 5.2).
Pikkutehtäviä
Lisäharjoite
Muokkaa luvun 3.5 VendingMachine
-luokkaa siten, että
käytät tavallisten sijoituskäskyjen sijaan yllä esiteltyjä
lyhennysmerkintöjä siellä missä mahdollista.
Luokan koodi löytyy Miscellaneous-projektista.
CarSim-tehtävä
Tehtävänanto
Nouda projekti CarSim. Se sisältää hyvän osan sovellusohjelmasta. Käyttöliittymä on annettu kokonaan valmiina. Keskeinen osa ohjelmaa kuitenkin puuttuu. Tehtäväsi on
- lukea luokan
o1.carsim.Car
dokumentaatio hartaudella, - kirjoittaa Scala-ohjelmakoodi, joka toteuttaa tuon täysin puutteellisena annetun luokan, ja
- testata, että se toimii dokumentaation mukaisesti, ja korjata tarvittaessa.
???
Annetussa luokan Car
raakileessa esiintyy useassa kohdassa
kolme peräkkäistä kysymysmerkkiä: ???
. Kyseessä on
Scala-kielen tarjoama tapa merkitä, että osa ohjelmasta on
toistaiseksi toteuttamatta. Jos ???
-lausekkeen yrittää
evaluoida (eli vaikkapa annetun Car
-luokan metodeita kutsua),
syntyy ajonaikainen poikkeustilanne.
Suosittelemme, että noudatat seuraavia työvaiheita.
1/6: Ilmentymämuuttujat (ainakin alustavasti)
Sinun on itse valittava ilmentymämuuttujat siten, että tarvittavat tilatiedot pysyvät tallessa olioissa metodikutsujen välilläkin. Osan muuttujista tulee olla yksityisiä, jotta niiden arvoja ei voi mielivaltaisesti muuttaa luokan ulkopuolelta.
Dokumentaatio kuvaa konstruktoriparametrit, ja annetusta koodistakin ne löytyvät. Osa
niistä on myös (perustellusti) määritelty ilmentymämuuttujiksi. Mitä muita oleellisia
piirteitä kullakin autolla on eli mistä muusta Car
-olion on pidettävä kirjaa, jotta
sen metodit voisivat toimia? Millaisiin muuttujiin nuo tiedot voisi tallentaa? Mitkä
ovat muuttujien tyypit ja roolit?
Kaikkia ilmentymämuuttujia ei välttämättä tarvitse keksiä heti. Voit myöhemmin palata lisäämään muuttujia, jos huomaat niille tarvetta.
Pitäydy pyydetyssä rajapinnassa
Älä lisää luokkaan julkisia osia, joita ei pyydetty. Yksityisiä osia voit lisätä vapaasti.
Sama ohje pätee kaikkiin niihin kurssin ohjelmointitehtäviin, joissa on annettu tarkka spesifikaatio toteutettavien luokkien julkisesta rajapinnasta.
Valinnainen vinkki ilmentymämuuttujista
Ilmentymämuuttujissa on tarpeen pitää kirjaa niistä asioista, jotka säilyvät metodikutsujen välilläkin. Näitä ovat muun muassa polttoaineen kulutus ja tankin koko, jotka onkin jo annetussa koodissa ilmentymämuuttujiksi merkitty.
Useat metodit käsittelevät auton tankissa olevan bensan määrää. Tuo tieto on pidettävä tallessa ilmentymämuuttujassa, jotta se ei katoa metodikutsujen välillä.
Metodit location
ja drive
käsittelevät auton sijaintia, jonka
on myös tallennuttava osaksi auton tietoja.
metersDriven
ja drive
tarvitsevat tietoa siitä, paljonko
autolla on siihen mennessä ajettu.
Muita ilmentymämuuttujia et tarvitse. Jos haluat pitää metodin sisäisesti tallessa jotakin tietoa, voit kirjata sen paikalliseen muuttujaan.
2/6: Helpommat(?) metodit
drive
on metodeista monimutkaisin. Unohda se toistaiseksi ja laadi toteutukset
muille metodeille yksitellen.
Kaksi fuel
-metodia?
Huomasitko, että luokassa on kaksi eri fuel
-nimistä metodia,
joilla on erilaiset parametriluettelot?
Nämä metodit ovat toisistaan ihan erilliset, mutta voit hyödyntää yhtä toisen toteutuksessa.
Hieman lisätietoa keskenään samannimisistä metodeista löytyy tämän autotehtävän jäljestä.
Valinnainen vinkki location
- ja metersDriven
-metodeihin
Valinnainen vinkki fuel
-metodeihin
Parametrillinen fuel
-metodi on hyvin samantapainen kuin
eräät aiemmissa tehtävissä laatimasi metodit (esim. nostot
pankkitililtä). Huomaa, mitä metodin tulee palauttaa. Käytä
paikallista apumuuttujaa.
Parametriton fuel
-metodi on toteutettavissa erittäin
yksinkertaisesti kutsumalla parametrillista fuel
-metodia
riittävän suurella parametriarvolla.
Valinnainen vinkki fuelRatio
- ja fuelRange
-metodeihin
3/6: Testaa luokkaasi irrallisena ohjelmakomponenttina
Kokeile ajaa annettu testiohjelma CarTest
, joka käyttää Car
-luokkaa varsinaisesta
kokonaisesta CarSim-simulaattoriohjelmasta irrallaan. Tuon testiohjelman pitäisi nyt
toimia muuten paitsi ajamisen osalta.
Voit muokata testiohjelmaa kattavuuden parantamiseksi. Voit myös kokeilla Car
-luokan
käyttöä REPLissä.
4/6: Testaa luokkaasi CarSim-sovelluksen osana
Käynnistä CarSim käynnistysoliosta o1.carsim.gui.CarSim
. Kokeile autojen luomista
ja tankkaamista graafisessa käyttöliittymässä. Lyhyt käyttöohje näkyy siinä ikkunan
alareunassa.
5/6: Toteuta myös drive
-metodi
Kuten dokumentaatiostakin käy ilmi, tässä tehtävässä voit olettaa auton liikkuvan suoraa viivaa pitkin, "linnuntietä". Joskus se jää matkan varrelle, kun bensa loppuu.
Jos auton pysähtymissijainnin määrittämiseen liittyvä matematiikka tuottaa vaikeuksia, niin näistä vinkeistä voi olla apua:
- Vaikka CarSim käyttääkin
Pos
-olionx
:ää jay
:tä kuvaamaan leveys- ja pituusasteita maapallon pyöreällä pinnalla, niin tämä tehtävä on pedattu sinulle siten, että voit edelleen ajatellaPos
-olioiden yksinkertaisesti kuvaavan pisteitä tavallisessa, litteässä, kaksiulotteisessa koordinaatistossa. - Unohda ohjelmointi hetkeksi, piirrä kaavio auton liikkeestä ja selvitä matemaattinen pulma ensin. Mieti vasta sitten, miten saat ongelman ratkaisun kirjoitettua Scalaksi.
- Sinun ei tarvitse mallintaa auton nopeutta. Riittää, kun huolehdit dokumentaation kuvaamista asioista.
Valinnainen vinkki tarvittavista laskutoimituksista
Trigonometriaa ei tarvita. Peruslaskutoimitukset (kerto-, yhteen-, jako-, vähennys-) riittävät.
Lisäksi voit hyödyntää luokan Pos
metodeita. Esimerkiksi jo tuttu
distance
on hyödyllinen, ja muitakin dokumentaatiossa kuvattuja voit maun mukaan ottaa avuksi.
Lisävinkkejä
Huomaa yksiköt: matkat metreinä, kulutus sataa kilometriä kohden.
Hankalin kohta saattaa olla sijainnin määrittäminen bensan loppuessa. Se onnistuu helpoimmin, kun lasket suhteen oikeasti ajetun matkan ja ajettavaksi määrätyn matkan (eli metodin toisen parametrin) välillä. Koska mallinnamme auton liikkeen suorana viivana kohti määränpäätä, auton kaksi koordinaattia muuttuvat samassa suhteessa.
6/6: Testaa lisää
Testaa ajamismetodia. Suosittelemme nytkin, että kokeilet sitä ensin irrallaan
CarSim-sovelluksen kokonaisuudesta CarTest
-pikkuohjelmassa.
Leiki sitten autoiluohjelmalla.
Miten autot ajavat CarSimissä?
Ehkä kummastelet, miten CarSimissä autolta sujuu mutkittelukin, vaikka toteutuksesi on suoraviivaisempi.
CarSim-sovellus kyllä käyttää juuri laatimaasi autoluokkaa mutta
taiten: se kuvaa lähtösijainnin ja määränpään välisen mutkittelevan
reitin pikkuisina suorina paloina ja kutsuu drive
-metodiasi
kullekin palaselle peräjälkeen. Jos haluat, saat palaset näkyviin
CarSimin Settings-valikosta.
Entä reitin haku? Siihen CarSim käyttää Here.com:in verkkopalvelua, joka muistuttaa esimerkiksi Google-yhtiön tarjoamia sijaintipalveluita. Myös karttatiedot sovellus noutaa ilmaisesta nettipalvelusta.
Kaikki tämä on tehty CarSimin valmiina annetussa koodissa, jota voit silmäillä mutta joka on monin paikoin sellaista, ettei siitä ohjelmoinnin aloittelija saane vielä tolkkua. Joka tapauksessa sen havainnon voit tehdä, että ohjelma voi käyttää toisten tahojen tarjoamia palveluja apunaan.
Palauttaminen
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
Kuormittamisesta
Samannimisiä metodeita
Äskeissä tehtävässä oli kaksi fuel
-metodia. Toinen otti yhden parametrin, toinen vain
tyhjän parametriluettelon. Kuten viimeistään tästä näkyy, luokassa (tai yksittäisoliossa)
voi mainiosti olla useita keskenään samannimisiä metodeita. Tämä on kuitenkin sallittua
vain, jos samannimisillä metodeilla on erilaiset parametriluettelot.
Saman nimen käyttöä sanotaan kuormittamiseksi (overloading). Kyse on sinänsä ihan
samasta kuin luvussa 1.7, jossa oli kaksi pystypalkki
-nimistä funktiota; tällä kertaa
vain kuormitit laatimasi autoluokan metodeita.
Metodin määrittelyyn kirjattu nimi sekä parametriluettelo kuuluvat metodin
puumerkkiin (eli signatuuriin; signature). Kun kutsut olion metodia —
olio.metodinNimi(parametrit)
— suoritettava metodi määräytyy sen mukaan, minkä
metodin puumerkki vastaa kutsussa esiintyviä tietoja. Kahta puumerkiltään identtistä
metodia ei samaan luokkaan voi määritellä.
Periaatteessa kuormitetut metodit voisivat tehdä jotakin keskenään ihan erilaistakin, mutta yleinen käyttö kuormittamiselle on laatia erilaisia variaatioita samasta toiminnosta kuten autotehtävässä yllä.
Kuormittaminen ja palautusarvojen tyypit Scalassa
Luvussa 1.8 oli ensi kerran puhetta siitä, että minkä tahansa Scala-funktion koodiin voi kirjata palautusarvon tyypin. Joissakin tilanteissa tämä on myös pakollista. Ehkä yleisin tällainen pakkotilanne on metodinimeä kuormittaessa, kun metodi kutsuu toista samannimistä metodia. Kutsuvalle "kaimalle" on määriteltävä palautusarvon tyyppi, jotta Scalan automaattinen tyyppipäättely toimisi oikein. Voit todeta asian itsekin seuraavasti.
Toteutitko parametrittoman fuel
-metodin kutsumalla parametrillista fuel
-metodia,
kuten vinkattiin? Jos teit niin, voit nyt kokeilla poistaa tyyppimäärittelyn
(kaksoispisteen ja Double
-sanan) metodin alusta. Saat virheilmoituksen overloaded
method fuel needs result type eli "kuormitetulle metodille fuel
tarvitaan
palautusarvon tyyppi".
Ilmiö on helppo havaita myös REPLissä:
class Luokka { def metodi(eka: Int, toka: Int) = eka + toka def metodi(luku: Int) = this.metodi(luku, luku) }<console>:13: error: overloaded method metodi needs result type def metodi(luku: Int) = this.metodi(luku, luku) ^ class Luokka { def metodi(eka: Int, toka: Int) = eka + toka def metodi(luku: Int): Int = this.metodi(luku, luku) }defined class Luokka
Tämä on nyt siis vain eräs Scalan pieni erikoisuus, ei sen keskeisempi asia. Onneksi virheilmoitus muistuttaa asiasta varsin selkeästi. Ja muista, että mille tahansa metodille saa aina kirjata palautusarvon tyypin koodiin.
Lisämateriaalia: ilmentymämuuttujia käsittelevistä metodeista
Nimeämishaaste: ilmentymämuuttuja vs. metodi
Keskenään samankaltaisia tilanteita:
- Luvun 3.2 tilausluokassa halusimme, että
kokonaishintaa voi tiedustella ulkopuolelta
(metodilla
kokonaishinta
) mutta ei voi ulkoisesti muokata suoralla sijoituksella (muuttujaanlisattyjenHinta
). Niinpä käytimme yksityisestivar
-muuttujaa ja erillistä julkista metodia, joka palauttaa sen arvon. - Sovelsimme samaa ratkaisumallia myös FlappyBug-peliin,
jossa ötökän ja esteen sijainnin muutokset
tapahtuvat rajatusti luokan sisäisesti käyttämässä
currentPos
-muuttujassa. Luokkien käyttäjille tarjotaan julkinenpos
-metodi. - Luvun 3.5
Match
-luokassa maalimäärät kirjattiin yksityisiin muuttujiin (awayCount
,homeCount
). Ulkopuolelta vastaavat arvot sai selville metodeilla (awayGoals
,homeGoals
). - Ehkä teit jotakin samantapaista myös äskeisessä tehtävässä?
Yhteistä noille tilanteille on, että ulkopuolinen "saa katsoa muttei koskea" tiettyä tietoa. Luokkien laatijan on valittava kaksi nimeä, jotka molemmat kuvaavat tavallaan samaa asiaa: toinen metodille ja toinen yksityiselle muuttujalle.
Tähän ei ole mitään patenttiratkaisua, ja eri ohjelmoijat tekevät eri tavoin.
Jos kahta hyvää nimeä ei keksi, niin kannattaa käyttää parempaa julkisen metodin nimenä ja huonompaa yksityisen muuttujan nimenä. Näin asetetaan etusijalle luokan käytön helppous.
Jotkut harrastavat lyhenteitä sisäisten ilmentymämuuttujien nimissä. Tällöin pitää kuitenkin varoa, että nimien ymmärrettävyys säilyy.
Jotkut tykkäävät käyttää etuliitteitä ilmentymämuuttujien nimissä, esim. mBuyer
(missä m
= member eli luokan jäsen) tai alaviivallinen _buyer
.
Eräillä kielillä ohjelmoidessa tyyli on usein tällainen:
buyer
(muuttuja) ja getBuyer
(metodi). Tämä tyyli ei kuitenkaan
priorisoi luokan käytön kätevyyttä. Scalassa ei ole tapana nimetä näin.
Useimmissa tämän kurssin ohjelmointitehtävissä julkiset nimet on spesifioitu etukäteen ja yksityiset voit keksiä itse.
Huomaa muuten, että tämä nimeämishaaste koskee nimenomaan
var
-muuttujia. val
-muuttujien osalta tilanne on yksinkertaisempi,
koska val
-muuttujaan ei voi sijoittaa uutta arvoa eikä tarvetta
erilliselle metodille ole.
Kysyttyä: eikö Scalassa yleensä käytetä "gettereitä" ja "settereitä" kuten esimerkiksi Javassa?
Yllä oli esimerkkejä ohjelmista, joissa yksityisen var
-muuttujan
yhteyteen oli määritelty ns. "getteri" eli olion ominaisuuden arvon
palauttava julkinen metodi. Kuitenkaan emme ole tehneet tällaisia
"gettereitä" useimmille ilmentymämuuttujille.
Scala-ohjelmissa on yleistä jättää muuttujia julkisiksi, kun kyseessä on olion ulospäin näkyvä ominaisuus. "Getterit" ovat pikemminkin poikkeus kuin sääntö.
Tarkastellaan esimerkkiä:
class Profile(val name: String, var status: String) {
// metodit tänne
}
Yllä profiilin nimestä ja statustekstistä kirjaa pitävät muuttujat
ovat julkisia. Niiden arvoja voi tutkia luokan ulkopuolelta ja
jälkimmäiseen voi myös sijoittaa vaikkapa käskyllä
munProfiili.status = "lomalla"
. Jos olisimme laatineet luokan
enemmän "Java-tyyliin", olisimme kirjoittaneet pidemmin:
class Profile(private val name: String, private var status: String) {
def getName = this.name
def getStatus = this.status
def setStatus(status: String) = {
this.status = status
}
// muut metodit tänne
}
Tällaisia "gettereitä" ja "settereitä" käytetään mm. Java-ohjelmoinnissa aivan jatkuvasti. Lukemattomien tyylioppaiden mukaan julkisia ilmentymämuuttujia tulisi Javassa karttaa kuin ruttoa, heinäsirkkoja ja raemyrskyä. Tämänkin kurssin taannoisella Java-kielisellä edeltäjällä käskettiin opiskelijoita näin:
Miksi moinen? Ja miksei tuo mahtikäsky esimerkiksi Scalassa päde, vaan voit huoleti kirjoittaa lyhyemmin? Onko Scalassa itse asiassa sittenkin aina kulissien takana eräänlaisia "gettereitä", vaikka emme niitä määrittelekään?
Näihin aiheisiin voit tutustua nettilähteiden kautta, jos siltä tuntuu. Tässä pari linkkiä:
- Perusteluja Java-käytännölle: Why use getters and setters?
- Scala-käytännön selitystä: Getters and Setters in Scala
Lisämateriaalia: konstruktoreista ja parametreista
Konstruktorin kuormittaminen
Tuossa oli puhetta metodien kuormittamisesta. Myös konstruktoria voi kuormittaa: voit määritellä erilaisia tapoja luoda luokasta ilmentymiä käyttäen erilaisia parametreja. Tällä kurssilla tosin ei tarvitse.
Tehdään kokeeksi pieni luokka. Tarkoitus on ensinnäkin, että voimme luoda luokasta ilmentymän antaen konstruktoriparametreiksi sanan ja luvun:
new Kokeilu("kissa", 100)res0: Kokeilu = olio, jonka sana on kissa ja luku 100
Tällaisen luokanhan voi määritellä näin:
class Kokeilu(val sana: String, val luku: Int) {
override def toString = "olio, jonka sana on " + this.sana + " ja luku " + this.luku
}
Mutta entä jos haluamme, että voimme luoda olion myös siten, että annamme vain luvun, jolloin käytetään oletussanaa "laama"? Näin:
new Kokeilu(10)res1: Kokeilu = olio, jonka sana on laama ja luku 10
Kolmantena vaihtoehtona voitaisiin antaa vain sana, jolloin käytetään oletuslukua 12345:
new Kokeilu("koira")res2: Kokeilu = olio, jonka sana on koira ja luku 12345
Vaihtoehtoiset olionluontitavat järjestyvät konstruktoria kuormittamalla, mille on Scalassa oma merkintätapansa:
class Kokeilu(val sana: String, val luku: Int) {
def this(sana: String) = this(sana, 12345)
def this(luku: Int) = this("laama", luku)
override def toString = "olio, jonka sana on " + this.sana + " ja luku " + this.luku
}
def this
aloittaa vaihtoehtoisen
konstruktorin määrittelyn. Sen perässä olevissa
suluissa ilmoitetaan, mitä parametreja tässä
luontitavassa vastaanotetaan.this(
...)
tarkoittaa
vapaasti muotoillen: "tee ilmentymä normaaliin
tapaan käyttäen suluissa olevia tietoja
konstruktoriparametreina". Esimerkiksi tässä
määritellään, että jos on annettu vain sana,
niin luodaan olio käyttäen tuota sanaa ja
lukua 12345.Konstruktorin kuormittaminen ei kuitenkaan ole ainoa tai välttämättä kätevin tapa lisätä joustavuutta olion luomiseen: katso seuraava laatikko.
Oletusparametriarvot
Seuraavasta luokasta voi luoda ilmentymän joko käskyllä
new Kokeilu2("laama", 453534)
tai pelkästään new Kokeilu2("laama")
.
class Kokeilu2(val sana: String, val luku: Int = 12345) {
override def toString = "olio, jonka sana on " + this.sana + " ja luku " + this.luku
}
Oletusparametriarvoja voi määritellä konstruktorien lisäksi myös metodeille.
Nimetyt parametriarvot
Äsken esiteltiin lyhyesti oletusparametriarvoja, jotka ovat joskus käteviä mutta joita sinun ei ole välttämätöntä määritellä tällä kurssilla.
Samaan kategoriaan kuuluvat myös nimetyt parametriarvot.
Haastavaa luettavaa
Hakusanoilla builder pattern löytyy haastavampaa lisäluettavaa konstruktoriparametrien tiimoilta aiemmin jo ohjelmoineille.
Kiinnostavaa mutta erittäin aloittelijaepäystävällistä materiaalia löytyy artikkelista Type-Safe Builder Pattern in Scala.
Yhteenvetoa
- Sovellus voi hyödyntää ulkoisten tahojen tarjoamia rajapintoja.
Jotkin tällaiset rajapinnat eli API:t ovat tarjolla verkon yli.
- Esimerkiksi tämän luvun sovellus käytti erään yhtiön karttapalvelua.
- Verkkopalvelujen hyödyntämistä opetellaan kunnolla vasta jatkokursseilla.
- Yleisille
var
-muuttujien muokkauskäskyille on tarjolla (mm.) Scalassa lyhennysmerkintöjä kuten+=
ja*=
. - Metodinimiä voi kuormittaa: luokassa voi olla useita erillisiä
metodeita, joilla on keskenään sama nimi mutta erilaiset
parametriluettelot ja eri toteutukset.
- Scalassa kuormitetulle metodille, joka kutsuu toista samannimistä, on erikseen kirjattava palautusarvon tyyppi ohjelmakoodiin.
- Lukuun liittyviä termejä sanastosivulla: API; kuormittaa, puumerkki eli signatuuri; syntaktinen sokeri.
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!
Kierrokset 1–13 ja niihin liittyvät tehtävät ja viikkokoosteet on laatinut Juha Sorva.
Kierrokset 14–20 on laatinut Otto Seppälä. Ne eivät ole julki syksyllä, mutta julkaistaan ennen kuin määräajat lähestyvät.
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, Joonatan Honkamaa, Jaakko Kantojärvi, Niklas Kröger, Teemu Lehtinen, Strasdosky Otewa, Timi Seppälä, Teemu Sirkiä ja Aleksi Vartiainen.
Lukujen alkuja koristavat kuvat ja muut vastaavat kuvituskuvat on piirtänyt Christina Lassheikki.
Yksityiskohtaiset animaatiot Scala-ohjelmien suorituksen vaiheista ovat suunnitelleet Juha Sorva ja Teemu Sirkiä. Niiden teknisen toteutuksen ovat tehneet Teemu Sirkiä ja Riku Autio käyttäen Teemun toteuttamia Jsvee- ja Kelmu-työkaluja.
Muut diagrammit ja materiaaliin upotetut vuorovaikutteiset esitykset on laatinut Juha Sorva.
O1Library-ohjelmakirjaston ovat kehittäneet Aleksi Lukkarinen ja Juha Sorva. Useat sen keskeisistä osista tukeutuvat Aleksin SMCL-kirjastoon.
Opetustapa, jossa 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+ on luotu Aallon LeTech-tutkimusryhmässä pitkälti opiskelijavoimin. Pääkehittäjänä toimii tällä hetkellä Jaakko Kantojärvi, jonka lisäksi järjestelmää kehittävät useat tietotekniikan ja informaatioverkostojen opiskelijat.
Kurssin tämänhetkinen henkilökunta on kerrottu luvussa 1.1.
name
jastatus
ovat yksityisiä.