The following does not typecheck:
interface A
interface B : A
interface SomeInterface {
fun covariant(): A
fun contravariant(arg: B)
}
class SomeImplementation : SomeInterface {
override fun covariant(): B { (...) } // strengthen
override fun contravariant(arg: A) { (...) } // weaken
}
even though the implementation is completely safe.
I encountered a need for this in the specific case of writing EDSLs:
interface EdslSpec {
fun primitive(closure: A.() -> Unit) // [A] covariant
}
class EdslImpl : EdslSpec {
fun primitive(closure: B.() -> Unit) // strengthen
}
This would allow the dsl user to rely on B
-specific things as long as we know EdslImpl
is used. But I imagine there are other use-cases as well (e.g. the implementation class trying to use it’s own interface implementations)