Generics - declaration site variance

3 0 0
                                        

Type parameters - These are generics parameters that will represent any of the data types during declaration and when invoke it will be substituted depending on the supplied argument which is inferred by the compiler.

Enclosed in angled brackets, you write down the type parameters and put it beside the class name.

syntax:

class Name<T>(t: T){ // statements}

==================

fun main(){

    val music1: Music<String> = Music("MTV music")

    music1.displayT()

    val music2 = Music(2022)

   music2.displayT()

}

class YourMusic<T>(val t: T){

    fun displayT(){

        println("Awards: $t")

    }

}

==================

Result:

Awards: MTV music

Awards: 2022


Terms: In Java that is related to generics.

1. Invariant - it never change. In Java the generics are invariant because the hierarchy is not based on the type parameters. Like the List<String> is not a subtype of List<Object> which we know that the mother of all mother class in java is Object. This is the reason why Java introduces the wildcard for generics.

2. covariant - upper bound generics. List<? extend Numbers>. Starting from Numbers down to its lowest subtype, you are allowed to use it.

3. contravariant - lower bound generics. List<? super Integer>. Starting from Integer up to its Mother class Object, you are allowed to used it.


Kotlin does not used wildcards. It uses a variance annotation. It provides a modifier in and out to specify which are allowed.

Two types of Declaration - site variance

syntax for out:

class Name<out T>{

    fun methodName(): T

}

1. out - The type parameter is used only in return statements where covariant usually happens


syntax for in:

class Name<in T>{

    fun methodName(t: T){ // statement }

}

2. in - The type parameter is used only in parameters where contravariant usually happens.

===============

fun main(){

    val music1: YourMusic<String> = YourMusic()

    println(music1.displayT("Man up"))

    val music2 = YourMusic<Int>()

    println(music2.displayT(2002)) 

}

class YourMusic<in T>{

    fun displayT(t: T): String{

        return "t: $t"

    }

}

================

Result:

t: Man up

t: 2002

Note: One requirement is to specify the type of the variable when creating an object. You can put it beside the variable or in the object side or both.

Kotlin ProgrammingWhere stories live. Discover now