Kotlin 中的部分 class 委托
Partial class delegation in Kotlin
如何在 Kotlin 中部分委托 methods/fields?
具体来说:这里我试图从接口 TraitA
继承 class User
并在包装器 StateA
中实现字段 marked: Boolean
。这将清理 User
实现,因为 marked
只是一个状态字段。请注意 TraitA
不能是 class 因为我想使用几个这样的接口:User() : TraitA by StateA, TraitB by StateB, ..
/* does not compile (Kotlin M12) */
interface TraitA {
var marked: Boolean
fun doStaffWithMarked() // must be overridable
}
class StateA() : TraitA {
override var marked = false
}
class User() : TraitA by StateA(){
override fum doStaffWithMarked() {
//...all fancy logic here...
}
}
另一种方法是在一个地方全部实施:
class User() : TraitA{
override var marked = false // ugly code
override fum doStaffWithMarked() {
//...
}
}
是否有 way/pattern 可以使用尽可能少的简单代码解决该问题? Code/bytecode一代对我来说不是一个选择。
更新
我不是很清楚,但请注意 doStaffWithMarked()
是 unique 每个 User
.
所以我可能会建议一个 'half-bad' 解决方案,其中包含 运行 次断言:
interface TraitA {
var marked: Boolean
/* must be overridden */
fun doStaffWithMarked() = throw UnsupportedOperationException()
}
class StateA() : TraitA {
override var marked = false
}
class User() : TraitA by StateA() {
override fum doStaffWithMarked() {
//...all fancy logic here...
}
}
问题仍然悬而未决,因为真正好的解决方案会在编译时检查doStaffWithMarked()
。
这是一个继承自 StateA
而不是委托的版本,但这不是很好:
interface TraitA {
var marked: Boolean
fun isMarked(): Boolean
}
abstract class StateA() : TraitA {
override var marked = false
}
class User() : TraitA, StateA() {
override fun isMarked(): Boolean {
return marked
}
}
这是一种有点不寻常的方法,我将 TraitA
委托给 StateA
的匿名实例
class User() : TraitA by object : StateA() {
override fun isMarked(): Boolean {
return marked
}
} {
}
不过老实说,我宁愿重新考虑 class 层次结构的设计。特别是,您可以将方法实现放在接口中(但不是 属性 值),因此如果 isMarked()
仅依赖于 marked
,您可以直接将它的实现放在 TraitA
中.您的代码将变为:
interface TraitA {
var marked: Boolean
fun isMarked(): Boolean {
return marked
}
}
class StateA() : TraitA {
override var marked = false
}
class User() : TraitA by StateA() {
}
编辑:单独的答案:
将TraitA
分成两个接口,然后委托一个并实现另一个:
interface TraitA {
var marked: Boolean
}
interface TraitAPlus : TraitA {
fun isMarked(): Boolean
}
class StateA() : TraitA {
override var marked = false
}
class User() : TraitA by StateA(), TraitAPlus {
override fun isMarked(): Boolean {
return marked
}
}
如何在 Kotlin 中部分委托 methods/fields?
具体来说:这里我试图从接口 TraitA
继承 class User
并在包装器 StateA
中实现字段 marked: Boolean
。这将清理 User
实现,因为 marked
只是一个状态字段。请注意 TraitA
不能是 class 因为我想使用几个这样的接口:User() : TraitA by StateA, TraitB by StateB, ..
/* does not compile (Kotlin M12) */
interface TraitA {
var marked: Boolean
fun doStaffWithMarked() // must be overridable
}
class StateA() : TraitA {
override var marked = false
}
class User() : TraitA by StateA(){
override fum doStaffWithMarked() {
//...all fancy logic here...
}
}
另一种方法是在一个地方全部实施:
class User() : TraitA{
override var marked = false // ugly code
override fum doStaffWithMarked() {
//...
}
}
是否有 way/pattern 可以使用尽可能少的简单代码解决该问题? Code/bytecode一代对我来说不是一个选择。
更新
我不是很清楚,但请注意 doStaffWithMarked()
是 unique 每个 User
.
所以我可能会建议一个 'half-bad' 解决方案,其中包含 运行 次断言:
interface TraitA {
var marked: Boolean
/* must be overridden */
fun doStaffWithMarked() = throw UnsupportedOperationException()
}
class StateA() : TraitA {
override var marked = false
}
class User() : TraitA by StateA() {
override fum doStaffWithMarked() {
//...all fancy logic here...
}
}
问题仍然悬而未决,因为真正好的解决方案会在编译时检查doStaffWithMarked()
。
这是一个继承自 StateA
而不是委托的版本,但这不是很好:
interface TraitA {
var marked: Boolean
fun isMarked(): Boolean
}
abstract class StateA() : TraitA {
override var marked = false
}
class User() : TraitA, StateA() {
override fun isMarked(): Boolean {
return marked
}
}
这是一种有点不寻常的方法,我将 TraitA
委托给 StateA
class User() : TraitA by object : StateA() {
override fun isMarked(): Boolean {
return marked
}
} {
}
不过老实说,我宁愿重新考虑 class 层次结构的设计。特别是,您可以将方法实现放在接口中(但不是 属性 值),因此如果 isMarked()
仅依赖于 marked
,您可以直接将它的实现放在 TraitA
中.您的代码将变为:
interface TraitA {
var marked: Boolean
fun isMarked(): Boolean {
return marked
}
}
class StateA() : TraitA {
override var marked = false
}
class User() : TraitA by StateA() {
}
编辑:单独的答案:
将TraitA
分成两个接口,然后委托一个并实现另一个:
interface TraitA {
var marked: Boolean
}
interface TraitAPlus : TraitA {
fun isMarked(): Boolean
}
class StateA() : TraitA {
override var marked = false
}
class User() : TraitA by StateA(), TraitAPlus {
override fun isMarked(): Boolean {
return marked
}
}