Kotlin的扩展(Extension)特性,你了解了吗?

2024年 3月 20日 87.7k 0

Kotlin扩展(Extension)特性允许为现有的类添加新的函数和属性,而无需继承该类或使用装饰器模式。可以在不修改原始类的情况下,为它添加新的行为。

在实际编程当中是非常有用的功能,具体场景如:我们想修改JDK中的String,想在它的基础上增加一个方法"lastElement() "来获取末尾元素,如果使用Java,我们是无法通过常规手段实现的,因为我们无法修改JDK的源码。

扩展函数

fun ClassName.functionName(parameters) {
    // 函数体
}

ClassName是要添加函数的类名,functionName是新函数的名称,parameters是函数的参数列表,函数体是函数的实际实现。

例如,我们可以向String类添加一个名为lastElement的扩展函数,用于来获取末尾元素:

fun String.lastElement(): Char? {
    if (this.isEmpty()) {
        return null
    }
    return this[length - 1]
}

// 使用扩展函数
fun main() {
    val msg = "Hello Wolrd"
    // lastElement就像String的成员方法一样可以直接调用
    val last = msg.lastElement() // last = d
}

lastElement函数就会在所有String对象上可用,而不需要修改String类的源代码。

扩展函数实现原理,反编译示例代码:

public final class ExtKt {
   public static final Character lastElement(String $this) {
      CharSequence var1 = (CharSequence)$this;
      if (var1.length() == 0) {
        return null
      }

      return  var1.charAt(var1.length() - 1);
   }
}

public static final void main() {
  String msg = "Hello Wolrd";
  Character last = ExtKt.lastElement(msg);
}

原本定义在String类型上面的扩展函数lastElement(),变成了一个普通的静态方法。另外,之前定义的扩展函数lastElement()是没有参数的,但反编译后的Java代码中,lastElement(String $this)多了一个String类型的参数。原本msg.lastElement()的地方变成了ExtKt.lastElement(msg),这说明,Kotlin编写的扩展函数调用代码,最终会变成静态方法的调用。

扩展属性

Kotlin中的扩展属性允许我们向现有的类添加新的属性,而无需继承该类或使用装饰者模式。扩展属性的语法与扩展函数类似,但是在属性名之前需要指定接收者类型。

还是以lastElement为例,以扩展属性的方式实现:

// 接收者类型
val String.lastElement: Char?
    get() = if (isEmpty()) {
            null
        } else {
            get(length - 1)
        }

fun main() {
    val msg = "Hello Wolrd"
    // lastElement就像String的成员属性一样可以直接调用
    val last = msg.lastElement // last = d
}

需要注意的是,扩展属性并不会真正地向类中添加新的属性,它只是提供了一种便捷的方式来访问现有类的属性或计算新的属性值。不管是扩展函数还是扩展属性,它本质上都会变成一个静态的方法。

应用场景

Kotlin的扩展特性允许开发者向现有的类添加新的方法和属性,而无需继承该类或使用装饰者模式。

  • 扩展第三方库:可以使用扩展函数为第三方库中的类添加额外的功能,而无需修改原始类的源代码。
  • 使代码更具可读性:可以通过为常用的类添加自定义方法,使代码更易读、更易维护。
  • 适配特定平台:可以使用扩展函数为特定平台(如Android或iOS)上的类添加平台特定的功能,而无需在通用代码中添加平台相关的逻辑。
  • 减少重复代码:可以通过扩展函数将一些重复的操作封装成新的方法,从而减少代码重复性。
  • 当然,扩展特性有一些使用限制:

  • 扩展函数不能访问私有或受保护的成员:扩展函数可以在类的外部定义,但不能访问类的私有或受保护成员。
  • 扩展函数不能被重写:由于扩展函数是静态解析的,因此不能被子类重写。
  • 不能在扩展函数中添加新的属性:扩展函数可以为现有类添加新的函数,但不能添加新的属性。
  • 不能在扩展函数中访问super关键字:扩展函数中无法使用super关键字来调用基类的函数。
  • 作用域限制:扩展函数的作用域是在导入它的包内,因此在其他包中无法直接使用。
  • Kotlin的扩展特性使用限制主要是为了保证代码的可靠性和可维护性。

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论