Kotlin的部分班级代表团

vod*_*dan 9 delegation multiple-inheritance kotlin

如何在Kotlin中部分委托方法/字段?

具体来说:这里我试图User从接口继承类TraitAmarked: Boolean在包装器中实现字段StateA.这将清理User实现,因为marked它只是一个状态字段.注意,TraitA不能是一个类,因为我想使用几个这样的接口: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...
    }
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是在一个地方实现所有:

class User() : TraitA{
    override var marked = false // ugly code

    override fum doStaffWithMarked() {
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有一种方法/模式可以用尽可能简单的代码来解决这个问题?代码/字节码生成不适合我.

UPDATE

我对此并不十分清楚,但请注意,每个人doStaffWithMarked()都是独一无二User.

所以我可能会建议使用运行时断言的"半坏"解决方案:

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...
    }
}
Run Code Online (Sandbox Code Playgroud)

问题仍然存在,因为一个非常好的解决方案会doStaffWithMarked()在编译时检查.

Kir*_*man 12

分裂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
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在语言级别支持这种模式会很酷。但不确定它会是什么样子。 (2认同)
  • Kotlin 的座右铭是让事情变得明确。我猜编译器可以允许您将接口委托给不完整的实现,但是这个解决方案使委托的内容和实现的内容一目了然。 (2认同)