Sobes.tech
Junior

Aké druhy generíkov poznáte?

sobes.tech AI

Odpoveď od AI

Invarianta, kovariancia a kontravariancia.

  • Invarianta: Typ List<A> nie je podtypom List<B> a naopak, aj keď A je podtypom B. Typ zostáva presne.
  • Kovariancia (out): Umožňuje používanie podtypov. List<A> je podtypom List<B>, ak A je podtypom B. Používa sa pre výstupné parametre (návratové hodnoty).
fun foo(list: List<out Number>) {
    // Môže čítať zo zoznamu (Number, Double, Int atď.)
    val number: Number = list[0]
    // Nemôže pridávať do zoznamu (nevieme, aký typ prvkov sa očakáva)
    // list.add(1) // Chyba kompilácie
}
  • Kontravariancia (in): Umožňuje používanie supertried. List<B> je podtypom List<A>, ak A je podtypom B. Používa sa pre vstupné parametre (argumenty).
fun foo(comparable: Comparable<in String>) {
    // Argumenty typu String (alebo jeho supertípy) môžu byť odovzdané
    val result = comparable.compareTo("hello")
    // Výsledky typu String nie je možné získať (nevieme, aký je typ výsledku)
    // val str: String = comparable.compareTo("world") // Chyba kompilácie
}

V Kotlin tieto koncepty implementujú pomocou anotácií out a in na parametroch typu. V Jave sa používajú wildcards (? extends pre kovarianciu a ? super pre kontravarianciu).

Typ Účel Kľúčové slovo (Kotlin) Wildcard (Java) Čítanie povolené Písanie povolené
Invariabilný Presná zhoda typu Nie Nie Áno Áno
Kovariantný Použitie podtypov (producent - "out") out ? extends T Áno Nie
Kontravariabilný Použitie supertípy (spotrebiteľ - "in") in ? super T Nie Áno