Calling Methods on Generic Interfaces

Below is a very simple illustration of what I am trying to do:

interface Event {
    fun value(): Int
}

class Event1: Event {
    override fun value() = 1
}

class Event2: Event {
    override fun value() = 2
}

interface EventConsumer<T> where T: Event {
    fun consume(event: T)
}

class Event1Consumer: EventConsumer<Event1> {
    override fun consume(event: Event1) {
        println(event.value())
    }
}

class Event2Consumer: EventConsumer<Event2> {
    override fun consume(event: Event2) {
        println(event.value())
    }
}

class EventManager {
    private val consumers: Map<KClass<*>, EventConsumer<*>> = mapOf(
            Event1::class to Event1Consumer(),
            Event2::class to Event2Consumer()
    )

    fun consume(event: Event) {
        val consumer = consumers[event::class]

        consumer?.consume(event)
    }
}

      

The last method call (consumer.consume ()) gives me a compiler error

Out-projected type 'EventConsumer <*>?' forbids the use of abstract pleasure consumption (event: T): Unit defined in EventConsumer '

I know that Kotlin is much stricter about generics than Java, which is probably why this doesn't work, but how could I implement something like this correctly?

+3


source to share


1 answer


Since you are building a map consumers

, it would be safe to do an uncontrolled cast to the correct typical EventConsumer type:



fun <T: Event> consume(event: T) {
    val consumer = consumers[event::class] as? EventConsumer<T>

    consumer?.consume(event)
}

      

0


source







All Articles