My goal is to have the interface methods accept the class type of the implementation. Here\'s the code I have written so far:
internal interface Diff
The reason why this "worked" in Java was because <T extends Diff>
uses the raw type Diff
. Don't do this!
The closest you can get is to use a recursive type bound:
interface Diff<T : Diff<T>> {
fun lessThan(other: T): Boolean
}
The problem is, you can substitute any other subtype of Diff
.
However, when using the Diff
, use the generic type constraint T : Diff<T>
:
fun <T : Diff<T>> diffUser(diff1: T, diff2: T) {
println(diff1.lessThan(diff2))
}
and any Diff
that doesn't implement Diff<SameType>
will not be accepted.
Example:
class CDiff(private val value: Int) : Diff<DDiff> { // <-- Wrong type!
override fun lessThan(other: DDiff) = value < other.value
}
class DDiff(val value: Int) : Diff<DDiff> {
override fun lessThan(other: DDiff) = value < other.value
}
fun test() {
diffUser(CDiff(3), CDiff(4)) // <-- Doesn't compile due to the generic constraint
diffUser(DDiff(3), DDiff(4))
}
This same approach is used by the Comparable
class.
Although this works, what you really want is a "self type" and this is not supported, although it was on the roadmap at some point. I believe JetBrains denied the request for this, though I cannot find the bug report.
This answer details a workaround in Java using the CRT pattern, though it is not necessarily type safe.