情境/问题
我想通过kotlin实现一个具有良好委托功能的库,但是我在想要将两个不同的接口委托给同一实现时遇到了困难。问题是,这两个接口具有共同的方法(其中一个接口是另一个接口的扩展)。
无法更改的库
所以有一个Base
接口,它被ExtendedBase
和Foo1
接口扩展。 还有一个Foo1Impl
类,它实现了Foo
和ExtendedBase
接口,实际上该库中有很多类似此的实现和接口。
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 {
// ...
}
该库的扩展(这是我想做的)
我想扩展这个库并创建自己的接口,以扩展一些 ExtendedBase
和 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
这些扩展会抱怨关于“继承了它的多个实现”,因为
Foo1
和ExtendedBase
都继承了Base
。但实际上很容易判断,因为只有一个可委派的实现:impl: T
。
我考虑过的事情,但不起作用的/没有用的
1. 多接口实现的语法(在kotlin中不存在)
如果有一种多接口实现的语法,可能像这样:
class FooBar1Impl<T>
constructor(impl: T): FooBar1, (ExtendedBase, Foo1) by impl
where T: Foo1, T: ExtendedBase
{ /* ... */ }
2. 类型参数声明的继承(JVM不支持)
如果JVM支持,就可以编写类似于以下内容,但现在不支持:
class FooBar1Impl<T>
constructor(impl: T): FooBar1, T by impl
where T: Foo1, T: ExtendedBase
{ /* ... */ }
3. 几乎可能:可以扩展的基础对象(仍然存在问题)
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
但这里,可以看到被压制的警告是问题所在。
4. 用于决定默认实现的语法(在 Kotlin 中不存在)。
class FooBar1Impl<T>
constructor(impl: T): FooBar1, [default] ExtendedBase by impl, Foo1 by impl
where T: Foo1, T: ExtendedBase { /* .. */ }
问题
有什么工作流程可以让我免于手动重写所有Base
方法?或者有其他任何解决方案使得这种扩展成为可能吗?
假设Base
有100个方法需要手动覆盖。