我的项目在很大程度上取决于Kotlin的授权和组成。委托属性是轻而易举的,但从概念上讲,我并不完全确定如何在函数依赖于其他组合属性的情况下实现函数委派。我想做这样的事情:
interface A {
val a: String
}
class AImpl: A {
override val a = "a"
}
interface B {
val b: String
}
class BImpl: B {
override val b = "b"
}
interface C<T> where T: A, T: B {
fun c() : String
}
class CImpl<T>(val ab: T) : C<T> where T: A, T: B {
override fun c() = ab.a + ab.b
}
// works
class ABC : A by AImpl(), B by BImpl()
// does not work
class ABC : A by AImpl(), B by BImpl(), C<ABC> by CImpl(this)
当然,这类事情可以通过以下方式实现:
interface A {
val a: String
}
class AImpl: A {
override val a = "a"
}
interface B {
val b: String
}
class BImpl: B {
override val b = "b"
}
interface C<T> where T: A, T: B {
fun c() : String
}
class CImpl<T>(val ab: T) : C<T> where T: A, T: B {
override fun c() = ab.a + ab.b
}
class AB : A by AImpl(), B by BImpl()
class ABC(ab: AB = AB(), c: C<AB> = CImpl<AB>(ab)) : A by ab, B by ab, C<AB> by c
但是这感觉很笨,因为它需要传递构造的对象,这些构造会膨胀构造函数的大小 - 对于我来说,在类本身的站点初始化对象会更加清晰,因为它们在类之外没有用处。使用委托和/或扩展是否有一种优雅的方式?
答案 0 :(得分:3)
您可以C
延长A
和B
,而不是将其传递给代理人。 e.g:
interface C : A, B {
fun c(): String
}
abstract class CImpl() : C {
abstract override val a: String
abstract override val b: String
override fun c(): String = a + b
}
class ABC : A by AImpl(), B by BImpl(), CImpl()
您也可以使用C
中的默认实施,而不使用CImpl
:
interface C : A, B {
fun c(): String = a + b
}
class ABC : A by AImpl(), B by BImpl(), C
答案 1 :(得分:0)
我不认为目前支持得很好,但有issue跟踪此功能和相关功能请求。 (参见Peter Niederwieser关于这个问题的评论。)