I have a scenario in my code where I would like a class to implement an interface for two separate types, like this example:
interface Speaker<T> {
fun talk(value: T)
}
class Multilinguist : Speaker<String>, Speaker<Float> {
override fun talk(value: String) {
println("greetings")
}
override fun talk(value: Float) {
// Do something fun like transmit it along a serial port
}
}
Kotlin is not pleased with this, citing:
Type parameter T of 'Speaker' has inconsistent values: kotlin.String, kotlin.Float
A supertype appears twice
I know that one possible solution is to implement the following code, where I implement the interface with <Any>
and then check the types myself and delegate them to their functions.
interface Speaker<T> {
fun talk(value: T)
}
class Multilinguist : Speaker<Any> {
override fun talk(value: Any) {
when (value) {
is String ->
internalTalk(value)
is Float ->
internalTalk(value)
}
}
fun internalTalk(value: String) {
println(value)
}
fun internalTalk(value: Float) {
// Do something fun like transmit it along a serial port
}
}
However, that feels like I'm removing type safety and communication about what the class is used for, and is asking for trouble down the line. Is there a better way to implement this in Kotlin? Additionally - what's the reasoning behind it not being allowed the way I indicated in the first sample? Aren't interfaces just a contract of signatures I'm required to implement, or is there something I'm missing involving generics here?