Kotlin学习快速入门(7)——扩展的妙用

打印 上一主题 下一主题

主题 911|帖子 911|积分 2733

原文地址: Kotlin学习快速入门(7)——扩展的妙用 - Stars-One的杂货小窝
之前也模模糊糊地在用这个功能,也是十分方便,可以不用继承,快速给某个类增加新的方法,本篇便是来讲解下Kotlin中扩展这一概念的使用
说明

先解释一下,扩展的说明,官方文档上解释:
Kotlin 能够扩展一个类的新功能,而无需继承该类或者使用像装饰者这样的设计模式
简单来说,就是可以不用继承来让一个类多出一个方法或属性(成员变量),可能这样说比较抽象,我们以一个简单的例子来说
比如说,我们需要用到以下功能:
判断String对象是否其是否为null或未空白字符串,如果为null或空白字符串,则返回true,否则返回false
此功能挺好实现,但我们想要实现此功能,无非就是3种方法:

  • 写个工具类StringUtil,然后传递有个String对象进去,方法返回
  • 写个新的类,让其继承于String类,之后再新增方法
  • 用装饰者模式,扩展类(这里不多解释装饰者模式,可以自己百度查阅下资料)
但上面的方法,估计第一种各位都明白,也是十分简单,但使用起来还是比较麻烦,还得将对象作为入参传递,如果使用Kotlin的扩展特性,还能变得更加简单
而剩下两种,改动均是较大,一般得看情况使用,也是不太推荐
扩展方法

我们以刚才上述说的功能为例,实现判断String对象是否其是否为null或未空白字符串,如果为null或空白字符串,则返回true,否则返回false此功能
语法及使用

首先,显示讲解下语法
  1. fun 类名.方法名(参数列表...):返回值{
  2.    
  3. }
复制代码
看起来稍微有些抽象,我们直接上示例:
  1. fun String.isBlankOrNullString(): Boolean {
  2.     return this == null || this.trim().length == 0
  3. }
复制代码
需要注意的是,方法里的this就是当前调用此方法的String对象
扩展方法使用:
  1. fun main(args: Array<String>) {
  2.     val str = ""
  3.     println(str.isBlankOrNullString())
  4. }
复制代码
PS: 这里的扩展方法写在了顶层,是全局可用的
注意点


  • 扩展方法会区分作用域(全局和局部)
  • 类中存在于扩展方法同名同参数列表,相当于重载,此时以扩展方法为主
  • 扩展方法可接收可空类型
扩展方法作用域

扩展方法的声明位置,会决定此扩展方法的作用域
如下面示例:
  1. fun main() {    val str = ""    println(str.isBlankOrNullString())}class User {    val str = ""}fun String.isBlankOrNullString(): Boolean {
  2.     return this == null || this.trim().length == 0
  3. }
复制代码
我们将方法写在了最外层(即与class关键字同级),此时,我们可以在任意的类中调用此方法
但如果我们稍微改一下,如下:
  1. fun main() {
  2.     val str = ""
  3.     //这里会报错!!
  4.     //println(str.isBlankOrNullString())
  5. }
  6. class User {
  7.     val str = ""
  8.     fun sayHello() {
  9.         //类中可以正常使用
  10.         str.isBlankOrNullString()
  11.     }
  12.     fun String.isBlankOrNullString(): Boolean {
  13.         return this == null || this.trim().length == 0
  14.     }
  15. }
复制代码

扩展方法重载问题

由于是声明方法,可能会出现方法名重名的情况,即我们Java基础中说到的重载关系
这里,如果出现了重载的情况(方法名和参数列表相同),会以类中的方法为主(即会忽略掉扩展方法)
上面此句,是根据文档上总结得来的,实际上也是测试通过
  1. fun main() {
  2.     Example().printFunctionType()
  3. }
  4. class Example {
  5.     fun printFunctionType() { println("Class method") }
  6. }
  7. fun Example.printFunctionType() { println("Extension function") }
复制代码
最后输出的是Class method
但这里有个奇怪的情况,我以String的扩展为例,测试发现与上述结论不一致!!
以下是我的测试代码:
  1. fun main() {
  2.     val str = ""
  3.     println(str.isNullOrBlank())
  4. }
  5. fun String.isNullOrBlank(): Boolean {
  6.     println("进入我们的方法里")
  7.     return this == null || this.trim().length == 0
  8. }
复制代码
最终输出:
  1. 进入我们的方法里
  2. true
复制代码
看着打印,这明显就是进到我们定义的扩展方法里啊
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

慢吞云雾缓吐愁

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表