Situation/Problem
I would like to extend a library via kotlin with nice delegation features, but I got stuck at a place where I want to delegate two different interfaces to the same impl. The problem is, that these two interfaces have common methods (one extends the other).
Library I cannot change
So there is a Base interface that is extended by both ExtendedBase and Foo1 interfaces. And a Foo1Impl that implements Foo and ExtendedBase, actually there are a lot of implementations and interfaces like that in the library.
interface Base: {
fun doBase()
fun doBase2()
// .. lots of methods
fun doBaseN()
}
interface ExtendedBase: Base {
fun doExtended()
fun doExtended2()
// .. lots of methods
fun doExtendedN()
}
interface Foo1: Base {
fun doFoo1()
}
class Foo1Impl: Foo1, ExtendedBase {
// some impl for doBase, doExtended and doFoo1
}
interface Foo2: Base {
fun doFoo2()
}
class Foo2Impl: Foo2, ExtendedBase {
// ...
}
// ... lots of interfaces and impls
interface FooN: Base {
fun doFooN()
}
class FooNImpl: FooN, ExtendedBase {
// ...
}
Extension of that library (This is what I would like to Do)
I want to extend this library and create my own interfaces that extend the functionality of something that is ExtendedBase and Foo[1..N]:
interface FooBar1: Foo1 {
fun doFooBar1()
}
class FooBar1Impl<T>
constructor(impl: T): FooBar1, ExtendedBase by impl, Foo1 by impl
where T: Foo1, T: ExtendedBase
{
override fun doFooBar1() {
println("foobar1")
}
}
//.. a lot of other extensions like FooBar[2..N] that all extended the bases with the same logic
These extensions would complain about inheriting multiple implementations of it because both Foo1 and ExtendedBase extend Base. But actually it would be easily decidable because there is only one implementation to delegate to: impl: T.
Things I thought about which do/did not work
1. Syntax for multi-interface-implementation (not existing in kotlin)
If there would be a syntax for multi-interface implementations, it might be possible like so:
class FooBar1Impl<T>
constructor(impl: T): FooBar1, (ExtendedBase, Foo1) by impl
where T: Foo1, T: ExtendedBase
{ /* ... */ }
2. Inheritance of typeparameter declarations (not possible for jvm)
If it would be possible for the jvm one could write something like this, but it is not:
class FooBar1Impl<T>
constructor(impl: T): FooBar1, T by impl
where T: Foo1, T: ExtendedBase
{ /* ... */ }
3. Nearly possible: base-object that can be extended (still problematic)
open class BaseExtension constructor(impl: Base) : Base by impl
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
class FooBar1Impl<T>
constructor(impl: T): BaseExtension(impl), FooBar1
where T: Base, T: ExtendedBase
But here you can see the suppressed warning is the problem.
4. Syntax for deciding the default impl (not existing in kotlin)
class FooBar1Impl<T>
constructor(impl: T): FooBar1, [default] ExtendedBase by impl, Foo1 by impl
where T: Foo1, T: ExtendedBase { /* .. */ }
Question
Is there any workflow that saves me from overriding all Base methods by hand? Or any other solution that makes this kind of extension even possible?
Imagine Base has like 100 methods that I would need to manually override.