
Exercise: Generic Consumer
In your project, you use a class that represents a consumer of some type. You have two implementations of this class: Printer and Sender. A printer that can accept Number should also accept Int and Double. A sender that can accept Int should also accept Number and Any. In general, a consumer that can accept T should also accept S if it is a subtype of T. Update the Consumer, Printer and Sender classes to achieve this.
abstract class Consumer<T> { abstract fun consume(elem: T) } class Printer<T> : Consumer<T>() { override fun consume(elem: T) { // ... } } class Sender<T> : Consumer<T>() { override fun consume(elem: T) { // ... } }
Example usage:
val p1 = Printer<Number>() val p2: Printer<Int> = p1 val p3: Printer<Double> = p1 val s1 = Sender<Any>() val s2: Sender<Int> = s1 val s3: Sender<String> = s1 val c1: Consumer<Number> = p1 val c2: Consumer<Int> = p1 val c3: Consumer<Double> = p1
This problem can either be solved in the below playground or you can clone kotlin-exercises project and solve it locally. In the project, you can find code template for this exercise in advanced/generics/Consumer.kt. You can find there starting code and example usage.
Once you are done with the exercise, you can check your solution here.
Playground
abstract class Consumer<T> { abstract fun consume(elem: T) } class Printer<T> : Consumer<T>() { override fun consume(elem: T) { // ... } } class Sender<T> : Consumer<T>() { override fun consume(elem: T) { // ... } } fun main(args: Array<String>) { val p1 = Printer<Number>() val p2: Printer<Int> = p1 val p3: Printer<Double> = p1 val s1 = Sender<Any>() val s2: Sender<Int> = s1 val s3: Sender<String> = s1 val c1: Consumer<Number> = p1 val c2: Consumer<Int> = p1 val c3: Consumer<Double> = p1 }