msr*_*rd0 5 java delegates delegation kotlin
至于我的理解,在Kotlin中委托实现的想法是避免看起来像这样的代码:
class MyClass(val delegate : MyInterface) : MyInterface
{
override fun myAbstractFun1() = delegate.myAbstractFun1()
override fun myAbstractFun2() = delegate.myAbstractFun2()
// ...
}
Run Code Online (Sandbox Code Playgroud)
相反,我们可以编写以下代码,它们应该这样做:
class MyClass(val delegate : MyInterface) : MyInterface by delegate
Run Code Online (Sandbox Code Playgroud)
现在,我想delegate成为一个可变变量,即我的代码如下所示:
var delegate : MyInterface = MyImplementation()
object MyObject : MyInterface by delegate
Run Code Online (Sandbox Code Playgroud)
因此,如果我delegate像第一个示例一样将自己的每个抽象方法委托给自己,那么更改值delegate的确会改变方法的行为.但是,上面的代码编译为此Java代码:
public final class MyObject implements MyInterface {
public static final MyObject INSTANCE;
// $FF: synthetic field
private final MyInterface $$delegate_0 = MyObjectKt.access$getDelegate$p();
@NotNull
public String myAbstractFun1() {
return this.$$delegate_0.myAbstractFun1();
}
@NotNull
public String myAbstractFun2() {
return this.$$delegate_0.myAbstractFun2();
}
}
Run Code Online (Sandbox Code Playgroud)
很明显,delegateKotlin编译器决定在创建MyObject最终字段时复制它,而不仅仅是使用字段,$$delegate_0当我更改值时,它不会被修改.delegate
是否有更好的解决方案,而不是手动委派每个方法?
遗憾的是,据我所知,无法通过更改原始属性内容来更改委托,但您仍然可以通过以不可变的方式工作并复制对象来执行类似的操作:
interface MyInterface {
fun foo():Int
}
data class MyClass(val delegate : MyInterface) : MyInterface by delegate
object ImplementationA: MyInterface { override fun foo() = 7 }
object ImplementationB: MyInterface { override fun foo() = 5 }
val objA = MyClass(ImplementationA)
println(objA.foo()) // returns 7
val objB = objA.copy(ImplementationB)
println(objB.foo()) // returns 5
println(objA.foo()) // still 7
Run Code Online (Sandbox Code Playgroud)
希望这仍然有用。