Code:
0: aload_1
1: ldc #12 // String base
3: invokestatic #18 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
6: aload_0
7: invokespecial #21 // Method java/lang/Object."<init>":()V
10: aload_0
11: aload_1
12: putfield #23 // Field base:Lcn/yan/test/InterfaceBase;
15: return
//编译器帮忙实现了委托对象的方法,并且调用了构造函数参数传递对象的对应方法
public void print(int);
Code:
0: aload_0
1: getfield #23 // Field base:Lcn/yan/test/InterfaceBase;
4: iload_1
5: invokeinterface #29, 2 // InterfaceMethod cn/yan/test/InterfaceBase.print:(I)V
10: return
}
[](
)kotlin 属性委托
-----------------------------------------------------------------------
对于 kotlin 的属性委托来说,我们有如下要求:
* 对于只读属性来说(val 修饰的属性),委托需要提供一个名为 getValue 的方法,该方法需要提供的参数如下:
* thisRef:需要是属性拥有者相同的类型或者是其父类型(对于扩展属性来说,这个类型指的是被扩展的那个类型)。
* property:需要是`KProperty<*>`类型或者是其父类型。
getValue 方法需要返回与属性相同的类型或者其子类型。
* 对于可变读写属性(var 修饰的属性),委托需要提供只读属性的 getValue 方法外,还需要提供一个名为 setValue 的方法,该方法需要提供的参数如下:
* thisRef:需要是属性拥有者相同的类型或者是其父类型(对于扩展属性来说,这个类型指的是被扩展的那个类型)。
* property:需要是`KProperty<*>`类型或者是其父类型。
* value:需要与属性的类型相同或是其父类型。
* getValue、setValue 方法既可以作为委托类的成员方法实现,也可以作为其扩展方法来实现。
* getValue、setValue 方法都必须要标记为 operator 关键字。对于委托类来说,它可以实现 ReadOnlyProperty 或是 ReadWriteProperty 接口,这些接口包含了相应的 getValue、setValue 方法。对于委托类来说,它也可以不实现上面两个接口,而单独提供符合约定的 getValue、setValue 方法,其效果是一样的。
我们看一个属性委托样例:
//【工匠若水 加微信 yanbo373131686 联系我,关注微信公众号:码农每日一题 未经允许严禁转载 https://blog.csdn.net/yanbober】
//属性委托方法定义有严格的格式要求
//两个方法的定义签名必须按照要求来,不能修改
class PropertyDelete {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "$thisRef, your deleted property name is ${property.name}"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("$thisRef, new value is $value")
}
}
class PropertyClass {
//通过属性委托,不用给 name 赋值,因为其 set 和 get 方法都被委托