I have a proposal which I think would fit nicely to Kotlin without threatening the language design consistency.
For interfaces consisting only of other interfaces, where such interface is expected, Kotlin could allow using a type which implements all these interfaces.
interface HasFoo { val foo: Foo }
interface HasBar { val bar: Bar }
interface HasFooAndBar: HasFoo, HasBar
class ProvidesFooBarBaz (
override val foo: Foo,
override val bar: Bar,
val baz: Baz,
)
: HasFoo, HasBar
val appContext = ProvidesFooBarBaz(...)
class ComponentNeedsFooBar (
val appContext: HasFooAndBar,
)
So far so good, Kotlin can do this. Here comes the trick:
val component = ComponentNeedsFooBar(
appContext = appContext
)
This would not go, since appContext
does not implement HasFooAndBar
, despite implementing all that HasFooAndBar
is.
So again: For interfaces consisting only of other interfaces, Kotlin could allow using a type which implements all these interfaces. This of course would be extended transitively to a tree of such “compound” interfaces, i.e. the check would pass if the used type transitively implements the nested interfaces. This check would not pass for interfaces which have anything besides extending other interfaces.
It is a very limited case of duck typing. I did not want to put “duck typing” to the title, because that has been discussed as a general idea; but here, it is relatively simple mechanism.
It would be very useful for a compile-time, type-safe dependency injection, at least.
As discussed here:
https://youtrack.jetbrains.com/issue/KT-13108/Denotable-union-and-intersection-types#focus=Comments-27-10988052.0-0
I was experimenting for a while with various features like delegates, inline functions, as
, but did not figure out any alternative that would be as elegant as these compound interfaces.
WDYT? Useful or not? Can you think of other use cases? Is there something such coming in near future Kotlin? Thanks.