Helsingin yliopisto / tietojenkäsittelytieteen laitos / Ohjelmointitekniikka (Scala) / © Arto Wikla 2016

19 Hyvin lyhyesti tyyppiparametroinnista

Muutettu viimeksi 19.4.2016 / Sivu luotu 3.4.2014 / [oppikirjan esimerkit] / [Scala]

Oppikirjan luku 19 esittelee Scalan hyvin monipuolista ja vahvaa tyyppiparametrointia. Ohjelmointikielten yhteydessä tällaista on tapana kutsua geneerisyydeksi eli käännösaikaiseksi tyyppiparametroinniksi.

Idea on se, että luokkia ja piirretyyppejä voidaan ohjelmoida yleiskäyttöisiksi sallimalla ilmentymän luojan antaa luotavalle oliolle tyyppejä parametreina. Tällaisia luokkia/piirretyyppejä onkin jo nähty monia: Array[Int], List[String], Map[Int,String], ...

Tällä kurssilla ehditään vain katsoa pienen pieni esimerkki:

class Kapseli[T] (private var arvo: T) {  // T on muodollinen
  def get() = arvo                        // tyyppiparametri
  def set(arvo: T) {this.arvo=arvo}
}

val luku = new Kapseli[Int](12)        // Tässä Int on todellinen
println(luku.get())  // 12             // tyyppiparametri
luku.set(666)
println(luku.get())  // 666

val jono = new Kapseli[String]("ihahaa")
println(jono.get())  // ihahaa
jono.set("miau")
println(jono.get())  // miau

val lista = new Kapseli[List[Int]](List(1,2,3))
println(lista.get())      // List(1, 2, 3)
lista.set(List(9,8,7,6))
println(lista.get())      // List(9, 8, 7, 6)

// jne...

Tekniikka on hyvin vahva, monipuolinen ja siksi myös vaativahko hallittava. Erityisen mielenkiintoisia asioita nousee esiin, kun tyyppiparametroituja luokkia ja piirretyyppejä aletaan asettaa yliluokka-aliluokka- ja ylityyppi-alityyppi-suhteisiin! Tähän liittyvät mm. käsitteet "kovarianssi" ja "kontravarianssi", jotka usein sekoittavat kokeneemmankin ohjelmointiekielten periaatteisiin tutustuneen henkilön... ;-)