I have a set of component interfaces
interface ITest<I> {
operator fun invoke(p: I)
}
interface OTest<O> {
operator fun invoke(): O
}
interface IOTest<I, O> {
operator fun invoke(p: I): O
}
and a corresponding functional interface
interface TestAdder<T> {
fun add_f(p: T) {} //default impl
}
that gets inherited to add the components from above to respective (functional) collection interfaces
interface ITestSet<I> : TestAdder<ITest<I>> {
val i_v: I
fun i_f1(p: I) {} // default impl
fun i_f2(p: I) {} // default impl
fun i_f3(p: I) {} // default impl
}
interface OTestSet<O> : TestAdder<OTest<O>> {
val o_v: O
fun o_f1(p: O) {} // default impl
fun o_f2(p: O) {} // default impl
fun o_f3(p: O) {} // default impl
}
interface IOTestSet<I, O> : TestAdder<IOTest<I, O>> {
val i_v: I
val o_v: O
// same as ITestSet<I>
fun i_f1(p: I) {} // default impl
fun i_f2(p: I) {} // default impl
fun i_f3(p: I) {} // default impl
// same as OTestSet<O>
fun o_f1(p: O) {} // default impl
fun o_f2(p: O) {} // default impl
fun o_f3(p: O) {} // default impl
fun io_f1(p: I): O
...
}
So far, so unnecessay: ideally IOTestSet<I, O>
should inherit the functionality defined in ITestSet<I>
and OTestSet<O>
:
interface IOTestSet<I, O> : ITestSet<I>, OTestSet<O>, TestAdder<IOTest<I, O>> {
fun io_f1(p: I): O
...
}
but obviously the TestAdder<T>
interface introduces inconsistency within the inheritance chain.
This smells like an age-old, archetypal paradigm (and probably even an XY) problem, still it seems I have to ask: