双重委派
在Kotlin中,一个类可以实现多个接口。 这是常识。 一个类还可以使用委托来实现众多接口,这些实现的实现来自传递给构造函数的任何委托对象。 例如:
class GeneticExperiment(human: Human, animal: Animal) : Human by human, Animal by animal interface Human {
fun eat()
fun sleep()
fun poop() } interface Animal {
fun bite() }
这个怪异的类继承了传递给构造函数的Human
和Animal
对象的功能。 如果没有委派,则必须在类中手动写出两个接口上的任何功能。
需要注意的重要一点是,“ Human
与Animal
不共享公共的父界面。
如果确实具有从公共接口扩展的接口,则将存在由于委托对象的实现冲突而导致的编译错误。 例如,代码:
class ShapeShifter(human: Human, weightLifter: WeightLifter) : Human by human, WeightLifter by weightLifter interface Human {
fun eat()
fun sleep()
fun poop() } interface WeightLifter : Human {
fun liftHeavyStuff()
fun pose() }
导致错误:
Delegation.kt: 80 : 1 : error: class 'ShapeShifter' must override public open fun eat(): Unit defined in dev.lankydan.ShapeShifter because it inherits many implementations of it class ShapeShifter(human: Human, weightLifter: WeightLifter) : Human by human, WeightLifter by weightLifter ^ Delegation.kt: 80 : 1 : error: class 'ShapeShifter' must override public open fun sleep(): Unit defined in dev.lankydan.ShapeShifter because it inherits many implementations of it class ShapeShifter(human: Human, weightLifter: WeightLifter) : Human by human, WeightLifter by weightLifter ^ Delegation.kt: 80 : 1 : error: class 'ShapeShifter' must override public open fun poop(): Unit defined in dev.lankydan.ShapeShifter because it inherits many implementations of it class ShapeShifter(human: Human, weightLifter: WeightLifter) : Human by human, WeightLifter by weightLifter ^
从错误中可以看到, ShapeShifter
类不知道采用哪个委托实现。 必须通过显式覆盖冲突功能来解决编译错误。 通过覆盖功能,您可以决定要使用的委托实现,或者可以提供一个新的委托实现。 此类的固定版本如下所示:
class ShapeShifter(
private val human: Human,
private val weightLifter: WeightLifter ) : Human by human, WeightLifter by weightLifter {
override fun eat() {
human.eat()
}
override fun sleep() {
weightLifter.sleep()
}
override fun poop() {
println( "💩" )
} } interface Human {
fun eat()
fun sleep()
fun poop() } interface WeightLifter : Human {
fun liftHeavyStuff()
fun pose() }
只有在Human
界面中声明的功能才需要手动覆盖
从这里稍微退后一步。 只要实现了所有子功能,则将编译实现子接口并将其功能委托给子父接口的类。 措辞很难。 一个例子应该有助于阐明我要说的话:
class ShapeShifter(copied: Human) : WeightLifter, Human by copied {
override fun liftHeavyStuff() {
println( "🏋️♂️" )
}
override fun pose() {
println( "💪" )
} } interface Human {
fun eat()
fun sleep()
fun poop() } interface WeightLifter : Human {
fun liftHeavyStuff()
fun pose() }
只需手动添加在WeightLifter
接口中声明的功能
总结一下:
- 一个类可以实现多个接口,并将其功能委托给一个或多个对象
- 具有扩展公共父级的多个接口的类可以委托每个接口的实现,但必须重写父级中定义的函数
- 实现子接口的类可以委派给其父级,只需要添加在子级中定义的功能。
翻译自: https://www.javacodegeeks.com/2019/09/implementing-multiple-interfaces-through-delegation.html
双重委派