文章目录

  • 扩展函数和扩展属性的实现
  • 为什么要用扩展函数和扩展属性
  • 学习交流

扩展函数给本来单薄的类添加了许多功能,今天我们来详细看一下扩展函数和扩展属性到底是什么,应该怎么用。

扩展函数和扩展属性的实现

我们都知道,Java 中,只有一个类型的成员属性和成员方法才能用“对象.属性 / 方法()”的方式调用,一个类型的对象是绝对不可能通过这种方法调用其他类里定义的方法(除非存在继承或实现关系)。而 Kotlin 提供的扩展函数和扩展属性打破了这一规则,它是怎么实现的呢?

首先看例子:

// Test.kt
fun <T> MutableList<T>.swap(indexA: Int, indexB: Int) {val temp = this[indexA]this[indexA] = this[indexB]this[indexB] = temp
}val Int.isOdd: Booleanget() = this and 1 == 1

我们在这里定义一个扩展函数 swap,它的接收者是 MutableList,作用是调换传入的两个索引对应的值。然后给 Int 类定义了一个扩展属性 isOdd,用来检查这个 Int 是不是奇数。

这时我们就可以这样调用它们了:

val list = mutableListOf(1, 2, 3)
list.swap(0, 1)
println(list)
// [2, 1, 3]val n = 3
println(n.isOdd)
// true

但想要在 Java 中调用它们,就要这么写了:

// import TestKt
List<Integer> list = new ArrayList<>();
list.add(1); list.add(2); list.add(3);
TestKt.swap(list, 0, 1);
System.out.println(list);int n = 3;
println(TestKt.isOdd(n));

实际上,所有的扩展函数和扩展属性都会被编译成一个方法,这个方法的第一个参数就是扩展的接收者,然后才是其它各个参数。对于扩展属性来说 ,因为编译后这个属性并不存在,所以不能像一般的类属性那样对它进行初始化,而是要自定义 getter 和 setter 来访问它。

为什么要用扩展函数和扩展属性

Java 里有许多工具类,比如 Collections、Arrays、Objects 等等,它们提供了一系列静态方法来充当工具函数,通过参数传入被操作的对象,既不直观又冗长无比。

比如对于 Integer.parseInt(String s),Kotlin 就用一个扩展函数替代了它:

inline fun String.toInt() = java.lang.Integer.parseInt(this)

虽然还是调用这个方法,但这样定义有两个好处,一是减少了代码量,二是形成了一个统一的标准,所有其他基本类型都可以重载这个方法,实现同一个行为。

从另一个角度来看,Kotlin 鼓励开发者 尽量精简类的定义,一个类只定义框架,工具函数可以通过外部扩展一点点地添加,尽量不改动原有的类。

学习交流

欢迎入群交流学习,Android、Java开发技术交流群

  • QQ群:810970432
  • email:geduo_83@163.com

Kotlin-简约之美-进阶篇(十):扩展函数和扩展属性相关推荐

  1. Kotlin-简约之美-进阶篇(三):Lambda的使用详解

    文章目录 Lambda介绍 Lambda的使用 Lambda表达式的特点 Lambda语法 实例讲解: Lambda实践 it 下划线(_) 匿名函数 闭包 android实战 总结 学习交流 Lam ...

  2. Kotlin-简约之美-进阶篇(四):访问权限控制

    文章目录 默认的访问修饰符 限制修饰符 可见性修饰符 sealed密封类 学习交流 默认的访问修饰符 在Kotlin世界中,无任何修饰的class.方法,等等默认就是public的,所以是隐式的 pu ...

  3. Kotlin-简约之美-进阶篇(十七):DSL的简单应用

    文章目录 1.原始方式 2. 空适配器模式 3. 高阶函数方式 4. DSL方式 学习交流 当接口的方法过多,而我们只需要其中一个方法时,例如TextView.addTextChangedListen ...

  4. Kotlin-简约之美-进阶篇(十一):高阶函数

    Lambda是什么 在讲高阶函数之前,必须要明白什么是Lambda,简单来讲,Lambda是一种函数的表示方式(言外之意也就是说一个Lambda表达式等于一个函数).更确切的说:Lambda是一个未声 ...

  5. php程序员进阶篇 [十问PHP程序员]

    1.首先看了PHP的源码API函数,对于许多口水仗的争论一笑而过,只是停留在脚本级别上的什么效率,安全...之争完全就是无稽之谈,没有深入理解API,所有的争论都是臆测和不科学的态度.你做了吗? 2. ...

  6. Activiti7工作流引擎:进阶篇(十) 多实例

    一:多实例基本示例 @Test void testStartAndComplete() {Map<String, Object> variables = new HashMap<&g ...

  7. Activiti7工作流引擎:进阶篇(十二) 加签和转签

    加签就是委派任务delegateTask,然后去解决任务resolveTask(并不是去真正的去完成任务). 转签完成后才能完成任务complete. 一:委派任务 A由于某些原因不能处理该任务可以把 ...

  8. Kotlin之美——DSL篇 和 如何让你的回调更具Kotlin风味

    如何让你的回调更具Kotlin风味 https://mp.weixin.qq.com/s?__biz=MzAwOTQ4Mzk2Nw==&mid=2458585682&idx=1& ...

  9. 【Kotlin】学习小记-基础篇

    Kotlin学习小记-基础篇 Kotlin的介绍 入门基础篇 属性声明 关于val和final的小Tips 参数 1.可变参数 2.命名参数 函数返回值 1.默认返回Unit值 2.返回Nothing ...

最新文章

  1. js变量以及其作用域详解
  2. 【任务脚本】更新jd年兽任务脚本,京东淘宝活动任务全自动程序
  3. 的注册表怎么才能删干净_油烟净化器怎么清洗才能清理干净呢?
  4. letecode [204] - Count Primes
  5. Java中三种字符串的拼接(++ , String.format , StringBuilder.append)
  6. axios发送网络请求
  7. Java AtomicInteger类源码解析
  8. pyexiv2修改图片exvif
  9. KITTI数据集简介与使用
  10. 朋友圈加粗字体数字_如何让你的朋友圈骚到脱颖而出?
  11. 印章如何去蜡_PS怎么制作蜡封印章的效果?
  12. 阿里巴巴29个屌炸天的开源项目
  13. linux 服务器远程开机,Linux 下实现远程开机
  14. [USACO13FEB]拖拉机Tractor
  15. STM32的USB例程JoyStickMouse代码分析
  16. Python框架之UnitTest
  17. JAVA 实现字符串(String)的模糊查找
  18. 跨平台应用 Qt 对决 HTML5
  19. mysql中replace函数的用法
  20. Redis批量启停脚本

热门文章

  1. 黑苹果-Minisforum u820 opencore0.6.9 config.plist
  2. CSR8670/CSR8675多国语言字库显示逻辑
  3. 衡水东方计算机学校地址,衡水东方计算机学校
  4. 数学建模的影响因素分析方法
  5. 我以为我对数据库索引十分了解,直到我遇到了阿里面试官。
  6. 中通新财报:业绩下滑背后仍是老问题
  7. 海康设备网络SDK开发NET_DVR_GetDeviceConfig
  8. 预测房价--基于python的线性回归模型
  9. 单反相机滤镜种类和作用
  10. php商城建站,php商城建站系统