Home Articles

在泛型的接口上调用方法

Asked
Viewed 1839 times
3

以下是我正在尝试做的一个非常简单的说明:

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)
    }
}

最后的方法调用(consumer.consume())给了我一个编译器错误

Out-projection类型'EventConsumer <*>?'禁止使用'public abstract fun consume(event:T):EventConsumer中定义的单位'

我知道Kotlin对泛型的要求比Java要严格得多,这可能就是为什么它不起作用,但是我如何正确地实现这样的东西呢?

1 Answer

  • 0

    由于您正在构建 consumers 映射,因此将未经检查的强制转换为正确的通用EventConsumer类型是安全的:

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

Related