Need a generics advise, how can I make the second ...
# announcements
p
Need a generics advise, how can I make the second override work?
Copy code
interface Animal {
    val id: String
    fun <T: Animal> withSound(sound: String): T
}

data class Dog(
    override val id: String
): Animal {
    // works
    override fun <T : Animal> withSound(sound: String): T {
        TODO("Not yet implemented")
    }

    // does not work
    override fun withSound(sound: String): Dog {
        TODO("Not yet implemented")
    }
}
t
oh @kqr thanks for the link. I was trying to figure out how to write
is that the *caller* of the method can decide
. so,
override fun <T : Animal> withSound(sound: String): T
works but it is responsibility of the caller to define
T
. if you want the responsibility to be shifted to the declarator (
Dog
in your case), I think
interface Animal<T : Animal<T>>
is what you want. but I saw crazy things being done with generics and kotlin generics are much more powerful than java one, somebody more expert might actually make your original solution work as you want
t
I'd say @thanksforallthefish is on the right track. This should work
Copy code
interface Animal<T: Animal<T>> {
    val id: String
    fun withSound(sound: String): T
}
data class Dog(
    override val id: String
): Animal<Dog> {
    override fun <T : Animal> withSound(sound: String): T {
        TODO("Not yet implemented")
    }
    override fun withSound(sound: String): Dog {
        TODO("Not yet implemented")
    }
}
sorry, didn't see you already posted this solution
yes, it is the "correct" way. It's not really nice and in some edge cases you might run into problems (if your generics get too fancy). But JVM generics don't offer any better solution