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
    }
}