java属性定义_Kotlin 真香系列:扩展函数和属性
❝ 本文将介绍 Kotlin 中的扩展函数和扩展属性,并用这两个特性来逐步优化代码的写法,希望大家学习这种特性并在实践当中做更多的扩展。
❞
在 Android 开发中,大家可能经常使用这样的代码来判断或设置视图的可见性:
if (view.getVisibility() == View.VISIBLE) {view.setVisibility(View.GONE);// ...
}
或者封装了一个 px 转 dp 的工具类,如果计算逻辑比较复杂,可能会写成这样:
int width = (textView.getWidth() + DisplayUtils.dp2px(40)) / 2 - DisplayUtils.dp2px(18);
如果在一行代码中 DisplayUtils.dp2px()
工具类使用非常多的话代码会很长,也会增加理解难度。
那么,如果使用 Kotlin 中的扩展函数或扩展属性去精简一下,就可以方便很多。下面来介绍一下。
1. 扩展函数
所谓扩展函数,就是对一个现有类扩展定义一个成员函数,不过该定义在类的外面。一般我们如果想对一个类封装一个 API 方法,但又不能直接修改该类时,就可以用到扩展函数。
扩展方法的一般格式如下:
fun 类名.方法名([参数 1, 参数 2, ...]): 返回类型 {方法体
}
下面,我们将判断或设置视图的可见性封装成扩展方法,并定义在一个 kt 文件的最外层:
// ViewExtensions.kt
fun View.isVisible(): Boolean {return visibility == View.VISIBLE
}fun View.setVisible(visible: Boolean) {visibility = if (visible) View.VISIBLE else View.GONE
}
在扩展方法中,可以使用这个类的公有的方法和属性,例如上面代码中的 getVisibility()
和 setVisibility()
。
之后,在 Kotlin 代码中所有的 View 类及它的子类都可以用这两个方法了:
if (view.isVisible()) {view.setVisible(false)// ...
}
下面我们来看看扩展方法转换成 Java 代码是什么样的:
public final class ViewExtensionsKt {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$setVisible, boolean visible) {Intrinsics.checkParameterIsNotNull($this$setVisible, "$this$setVisible");$this$setVisible.setVisibility(visible ? 0 : 8);}
}
可以看出来转成 Java 代码后,将这个要扩展的类换成静态方法的第一个参数了,而原扩展方法的参数列表变成了从第二个参数开始定义,因此,我们可以按如下方式在 Java 中使用该扩展方法:
if (ViewExtensionsKt.isVisible(view)) {ViewExtensionsKt.setVisible(view, false);
}
至于怎么查看 Kotlin 转成的 Java 代码,方法如下:
- 在 Android Studio 顶部菜单中找到 「Tools → Kotlin → Show Kotlin Bytecode」;
- 在右侧的 「Kotlin Bytecode」 窗口中点击 「Decompile」 按钮,就可以看到对应的 Java 代码了。
这里还有个小技巧,如果大家不喜欢 Kotlin 文件转成 Java 后默认的类的名字(例如上面的 ViewExtensionsKt
),我们还可以自定义要转成 Java 的类名。
例如,在上例中的 ViewExtensions.kt
文件的顶部添加一行如下代码:
@file: JvmName("ViewUtils")
这样转成 Java 的类名就是 ViewUtils
了,如下:
public final class ViewUtils {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$setVisible, boolean visible) {Intrinsics.checkParameterIsNotNull($this$setVisible, "$this$setVisible");$this$setVisible.setVisibility(visible ? 0 : 8);}
}
2. 扩展属性
Kotlin 除了可以扩展函数,还可以扩展属性。但是这个属性并不会保存在对象里,所以我们使用它时需要实现 「getter」 函数,如果是可变对象,则还要实现 「setter」 函数。格式如下:
val 类名.属性名: 类型get() {方法体}var 类名.属性名: 类型get() {方法体}set(value) {方法体}
下面,为视图扩展一个属性来判断其可见性:
val View.isVisible: Booleanget() {return visibility == View.VISIBLE}
在 Kotlin 中,当方法体内只有一条 return 语句时是可以简写的,如下:
val View.isVisible get() = visibility == View.VISIBLE
接着,将该属性改为 var
,重写 「setter」 方法来设置可见性:
var View.isVisibleget() = visibility == View.VISIBLEset(value) {visibility = if (value) View.VISIBLE else View.GONE}
这样,在 Kotlin 中就可以这么使用了:
if (view.isVisible) {view.isVisible = false// ...
}
我们再来看看扩展属性的定义转成 Java 代码是什么样子的:
public final class ViewUtils {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);}
}
大家可以看到,扩展属性和扩展方法转成的 Java 代码是一样的,因此在 Java 中使用的时候也是一样的。
最后再说个 dp 转 px 的例子,我们可以对 Number
类扩展一个属性,代码如下:
val Number.dp get() = round(toFloat() * Resources.getSystem().displayMetrics.density).toInt()
这样我们就可以直接使用 18.dp
、0.5.dp
这种形式将一个数字转成对应的 dp 大小,是不是很简洁?
3. Kotlin 扩展库
其实,Google 官方已经为我们扩展了很多实用的函数和属性,比如 https://developer.android.com/kotlin/ktx。
大家有兴趣的可以去引入一下慢慢探索~
参考
- 《Kotlin 实战》
java属性定义_Kotlin 真香系列:扩展函数和属性相关推荐
- TypeScript真香系列-高级类型
前言 TypeScript真香系列的内容将参考中文文档,但是文中的例子基本不会和文档中的例子重复,对于一些地方也会深入研究.另外,文中一些例子的结果都是在代码没有错误后编译为JavaScript得到的 ...
- 「真香系列」新物种首发亮相 聚划算爆款孵化玩法升级
从普通商品到优质好物,差的便是那一句"真香". 2022聚划算99划算节,聚划算首发「真香系列」,为消费者精选了一批价格香.品质香.服务香的「十三香」好物.不过,聚划算的" ...
- android 小米相机问题吗,如果小米10把相机优化到位,那这款机器属于真香系列!...
如果小米10把相机优化到位,那这款机器属于真香系列! 2020-05-12 22:42:42 32点赞 9收藏 15评论 今年小米10给人印象最深的是,它涨价了.发布会当时3999元起步就劝退了不少人 ...
- java实体字节属性定义_Java字节码方法表与属性表详解
而这些字节其实对应的信息是它: 所以问题就来了,aload_0不是助记符信息么,怎么就能够跟字节码文件中的字节对应上呢?所谓助记符其实也就是帮忙我们去记忆的符合,在底层其实也是对应的一个个十六进制的数 ...
- Java——(1)定义一个学生类Student,包含属性:姓名(String name)、年龄(int age) (2)定义Map集合,用Student对象作为key
分析以下需求,并用代码实现: (1)定义一个学生类Student,包含属性:姓名(String name).年龄(int age) (2)定义Map集合,用Student对象作为key,用字符串(此表 ...
- 真香系列之 Golang 升级
Golang 以前的依赖管理一直饱受诟病,社区的方案也层出不穷,比如 vendor, glide, godep 等.之前的依赖管理一直是依靠 GOPATH 或者将依赖代码下载到本地,这种方式都有劣势. ...
- JVM真香系列:.java文件到.class文件
认识JVM 什么是JVM JVM 全称 Java Virtual Machine,也就是我们耳熟能详的 Java 虚拟机.它能识别 .class后缀的文件,并且能够解析它的指令,最终调用操作系统上的函 ...
- 数据结构与算法邹永林PDF_真香系列:耗时大半个月收整全套「Java架构进阶pdf」没白费,终于可以安心备战2021了!...
2021就这么来了,马上就要开启备战今年的"金三银四"了.辛亏在2020的最后半月花了我大半个月时间收整了全套的「Java架构进阶pdf」,这一波下来,刷完你就会知道,真真香啊,我 ...
- 真香系列!Java工程师面试该怎么准备
前言 对Java开发的知识点进行深入的学习,并打算做成系列,先从基础常用的重点**(面试点)**知识开始,后续会陆续扩展,加油! 涉及到底层的可能代码块会多点,但要学习底层不看代码看啥?代码说明一切! ...
最新文章
- pageContext.findAttribute()与pageContext.getAttribute()的区别
- ksql中定义的本体在dataModel中不存在
- 文件服务器+好处,文件服务器 好处
- 【C语言入门教程】2.2 常量 与 变量
- bufg和bufgp_如何将自己写的verilog模块封装成IP核(一)
- Ecere SDK:用于GUI和图形的跨平台工具包
- 解释Linux进程的父子关系,Linux进程管理
- python super().__init__()_python——多继承使用super().__init__ 发生的状态
- BZOJ 2432 兔农
- css基础知识汇总8
- pandas 删除特定行根据条件_记录21个Pandas技巧
- 读书笔记(10)网络规划与设计
- 巧用京东物流分享链接批量查询多个京东快递的物流信息
- 【国家集训队】跳跳棋(LCA+二分答案)
- 逝去的岁月,回忆的青春
- Oracle存储过程
- 江西宜春三名公务员擅自驾公车钓鱼被通报-公车钓鱼-公务员-公车
- memcached(十三)注意事项
- 最新360安全卫士在线安装版
- 一键抠图:一款简单好用的图片处理软件(工具详资源)