目录
1.简介及带来的好处
2.扩展函数的使用
3.扩展的本质
4.扩展属性
5.总结
一、简介及带来的好处
Kotlin中有个特别好用的特性叫扩展。可以给已有的类添加额外方法及属性,并且不需要通过修改源码的方式或通过继承的方式来修改。
在Android开发过程中,我们经常会有用到的一些工具方法。如字符串转Uri,dp转px,px转dp,根据资源id获取资源,设置view的可见性等。
拿设置view的可见性举例,在使用中有时会像下面这样调用.
if (mBtn.getVisibility() == View.VISIBLE) {
mBtn.setVisibility(View.GONE);
}
复制代码
如果在代码中需要修改的view比较多的话代码会很长。
那么,如果使用 Kotlin 的扩展去精简一下,就可以方便很多。可以直接通过下面方式调用即可实现view的隐藏和显示的功能。
mBtn.hide()
复制代码
二、扩展函数的使用
接着上一节来例子来说,我们要如何去实现拓展方法,使得在代码中能够如此调用呢?
那么按照图中的,我们定义如下方法即可.View作为receiver type,使用this来访问对象,并修改对象的属性。
fun View.hide(){
if (this.visibility == View.VISIBLE) {
this.visibility = View.GONE;
}
}
复制代码
通过拓展方法,我们可以很方便的为现有的类进行功能拓展,且无需通过继承的方式进行
三、扩展的本质
上面介绍了拓展方法的使用,心中难免会有个疑问就是Kotlin拓展是如何实现的?
我们先将上面实现的方法反编译为JAVA代码[2]。
public final class UIUtils {
//第一个参数即为Receiver对象
public static final void hide(@NotNull View $this$hide) {
Intrinsics.checkParameterIsNotNull($this$hide, "$this$hide");
if ($this$hide.getVisibility() == 0) {
$this$hide.setVisibility(8);
}
}
}
复制代码
从反编译的代码可以看出。拓展函数是一个静态方法,方法的第一个参数即为Receiver接收者的对象。
四、扩展属性
除了拓展函数外,我们还可以拓展属性。例如下面的代码,
var View.isVisible: Boolean
get() = visibility == View.VISIBLE
set(value) {
visibility = if (value) View.VISIBLE else View.GONE
}
//使用时,只需要下面一行即可
mBtn.isVisiable = false
复制代码
其反编译出来的代码,亦是静态方法。所以扩展属性实际并没有为类增加属性。
public final class EventKt {
public static final boolean isVisible(@NotNull View $this$isVisible) {
Intrinsics.checkParameterIsNotNull($this$isVisible, "$this$isVisible");
return $this$isVisible.getVisibility() == 0;
}
public static final void setVisible(@NotNull View $this$isVisible, boolean value) {
Intrinsics.checkParameterIsNotNull($this$isVisible, "$this$isVisible");
$this$isVisible.setVisibility(value ? 0 : 8);
}
}
复制代码
五、总结
Kotlin中扩展能够在无需继承的情况下,为一个类扩展新的功能。能够使得代码更为的简洁。 通过反编译分析后,可以知道扩展的本质就是实现了一个静态方法。
[1][让人爱不释手的Kotlin扩展(Extensions)技术探Extensions秘与应用] (doc.devio.org/as/book/doc…)
[2]如何查看 Kotlin 编译后的Java 代码,方法如下:
在 Android Studio 顶部菜单中找到 Tools -> Kotlin ->Show Kotlin Bytecode;
在右侧的 Kotlin Bytecode 窗口中点击 Decompile 按钮,就可以看到对应的 Java 代码了。