本节将着重介绍扩展函数
Kotlin 中有一个非常大的优势,就是可以静态的给一个类扩展它的成员方法,以及成员变量
扩展函数
首先扩展函数也是一个函数,所以也需要 fun
关键字进行声明,后面紧跟着的是你需要扩展的类的类名, 比如示例中是给 File 类扩展一个成员方法,之后是一个 .
它用来分割类名和函数名,后面紧跟着的是扩展函数名,后面则与普通函数声明无异,参数、返回值以及函数体。下面我们看到的示例实际上是 Kotlin 标准库中 File 的扩展函数。
如何使用呢?很简单,在 Kotlin 中,可以直接在类的对象上面调用这个扩展函数:
特别地,在 Java 代码调用时
首先,我们需要 new 一个 Java 的对象,其次我们需要注意是,这个扩展函数并不是这个类本身的函数,而是我们扩展出来的,它在编译的时候会被编译到那个类所对应的 class 中去。所以在 Java 中我们实际上是调用 FileKt 这个类中的扩展方法,另外还需要一点注意的是,扩展函数的第一个参数是需要扩展的类的对象即示例中的 file 对象,示例如下:
扩展函数需要大家注意的一点就是,它是静态的给一个类添加成员变量和成员方法。
扩展函数的主要用途是对一些第三方 SDK,或者说那个类是你不能控制的,你要想给它新增些你需要用到的方法时会用到的函数。
扩展函数的静态解析
为什么是静态的呢?下面给出一个示例。
示例中,open 表示“不 final”,即可以继承,声明一个 open 的 Animal,Dog 类继承自 Animal,给 Animal 和 Dog 添加扩展函数 name,并给 Animal 添加扩展函数 printName 执行 Dog().printName(Dog()) :
它的执行结果我们发现是 animal,而不是我们的 dog,为什么是这样的呢?这是因为 Kotlin 的扩展函数实际上是静态的给一个类添加的方法,它是不具备运行时的多态效应的。
我们看一下这个类编译之后的样子:
你会发现扩展函数会被编译成 public static
修饰的方法,且第一个参数是需要扩展的类的对象。
示例中需要注意的是,printName 扩展函数接受两个参数,第一个是需要扩展的类 Animal 对象另外一个是我们声明的扩展函数的参数。
最后,我们看 main 方法中我们的 Dog 对象被强转成 Animal 传递给 printName,printName 中 调用的 name 方法选择的是带有 Animal 参数的方法,而不是我们想象的带有 Dog 参数的 name 方法。
即扩展函数不具备运行时的多态效应。
查看 Kotlin 对应的 Java 文件
以上就是本节内容,欢迎大家关注~