Welcome to our in-depth guide on Kotlin Covariance (out)! In this tutorial, we'll learn about how Kotlin handles inheritance with generic types, focusing on covariance out. By the end of this lesson, you'll have a strong understanding of this important concept, backed by practical examples. š
Covariance (out) is a concept in Kotlin that allows a subtype to be assigned where its supertype is expected. In other words, when a supertype contains a generic type parameter, and the subtype extends the supertype, you can use a less restrictive type for the subtype's version of the generic type.
Let's dive into an example to understand this better:
// Defining our base class and interface
open class Animal<out T> {
fun showType() {
println("Base type: ${this::class.java.simpleName}<$T>")
}
}
interface Presentable<in T> {
val presentableType: T
}š” Pro Tip: The out keyword for the type parameter in the Animal class indicates that it is covariant and can only be extended with less restrictive types.
Now let's create some concrete examples of animals and a simple interface for presenting them.
// Defining a Dog and Cat classes
class Dog : Animal<String>(), Presentable<String> {
override val presentableType: String = "Dog"
}
class Cat : Animal<String>(), Presentable<String> {
override val presentableType: String = "Cat"
}Here, we've created a Dog and Cat class that both extend the Animal class and implement the Presentable interface. Both classes use String as their generic type, indicating that they're covariant with their parent Animal class.
Now, let's see how we can work with these covariant types:
fun main() {
val animalList: List<Animal<*>> = listOf(Dog(), Cat())
// Iterate through the list and print each animal's type
for (animal in animalList) {
println("Animal type: ${animal::class.java.simpleName}<${animal.showType()}>")
}
}In this code, we've created a list of Animal objects, regardless of their concrete type (Dog or Cat). When we iterate through the list and call the showType() method, we can see that the type printed is always the concrete type of the animal (either "Dog" or "Cat").
What is the benefit of using covariance out in Kotlin?
By now, you have a good understanding of Kotlin Covariance (out). With this knowledge, you'll be able to write more flexible and reusable code, especially when dealing with generic types and inheritance hierarchies. Happy coding! š”