Kotlin高级用法之<扩展函数/属性>

Kotlin 能够对一个类或接口扩展新功能而无需继承该类或者使用像装饰者 这样的设计模式。 这通过叫做扩展的特殊声明完成。

说人话就是,在不继承或修改原类的前提下,给已有类增加新功能的方法

1.Kotlin 扩展函数

markdown 复制代码
扩展函数写法:

fun 扩展者类型.函数名(参数列表): 返回类型 {
    // 函数体
}

-   **扩展者类型**:你要扩展的类,比如 `String`、`Int`、`View` 等。

-   **函数名**:扩展的方法名。

-   **参数列表**:正常函数参数。

-   **返回类型**:可以有返回值,也可以是 `Unit`。

扩展函数是 Kotlin 的一个核心特性,可以给已有类"额外添加方法",而不需要继承或修改原类

1.1:扩展函数特点

  • 无需继承

    不用创建子类或修改源代码,就可以给类增加方法。

  • 调用方式和普通方法一样

    看起来像是这个类本身的方法,但底层其实是静态函数调用。

  • 不能访问类的私有成员

    扩展函数只能调用类的公有 API。

1.2:扩展函数生效和调用顺序

Kotlin 的 扩展函数 从语法上看像是类的方法,但底层实现其实是 静态方法 ,并不是修改了类本身。它是通过 编译器在调用时做"静态分发" 来实现的。

编译器静态分发:

大白话理解,编译器在编译apk时将 扩展方法编译成一个静态方法,且将调用对象最为参数传入这个静态方法,调用的时候直接执行.

  • 编译器在编译时把扩展函数 转换为静态方法

  • 第一个参数就是扩展函数的 接收者对象(this)

  • 调用的时候直接调用这个静态方法 → 实现了"静态分发"

kotlin 复制代码
1: 创建扩展函数
ExtendUtil.kt

fun String.safeAppend(content: String): String = this + content


2:编译后扩展函数会变为静态方法 (会将对象当参数传进去)
//自动生成的类,名称基于文件名 + "Kt"
ExtendUtilKT{
    // 扩展函数被转换为静态方法
    // 第一个参数是接收者对象(原 String 实例)
    public static final String safeAppend(String $this, String content) {
        // 原 Kotlin 中的 "this + content" 被转换为对参数的操作
        return $this + content;
}

3. 编译时会将 调用方法也转换一下
"测试".safeAppend("1")
 编译后会变为  
String result = ExtendUtilKT.safeAppend("测试", "1");

所以会认为是对象直接调用其实不是  对象只是作为参数传递进去的

1.3 扩展函数示例

kotlin 复制代码
fun View.show() {
    this.visibility = View.VISIBLE
}

fun View.hide() {
    this.visibility = View.GONE
}

// 使用
button.show()
textView.hide()

2.扩展属性

Kotlin 的扩展属性(Extension Properties)是另一种扩展特性,允许你为已有的类添加新的属性,而无需修改类的源代码。与扩展函数类似,它也是一种编译期的语法糖,不会真正改变目标类的结构。

css 复制代码
// 定义扩展属性 val/var 类名.属性名: 类型 get() = // getter 逻辑 // 扩展属性不能有初始化器,也不能有幕后字段(backing field)

关键特点

  1. 没有幕后字段 :扩展属性不能像普通属性那样拥有 field 关键字对应的幕后字段,因此必须显式提供 getter(对于 var 还需要 setter)。
  2. 本质是函数 :扩展属性在编译后会被转换为一对 getter/setter 静态方法(类似扩展函数)。
  3. 不能初始化 :由于没有幕后字段,无法在定义时赋值(如 val String.len = 10 是错误的)。
markdown 复制代码
### 关键特点

1.  **没有幕后字段**:扩展属性不能像普通属性那样拥有 `field` 关键字对应的幕后字段,因此必须显式提供 getter(对于 `var` 还需要 setter)。
1.  **本质是函数**:扩展属性在编译后会被转换为一对 `getter/setter` 静态方法(类似扩展函数)。
1.  **不能初始化**:由于没有幕后字段,无法在定义时赋值(如 `val String.len = 10` 是错误的)。

注意事项

  • 扩展属性不能访问目标类的私有 / 受保护成员,只能使用公开 API。

  • 对于 var 类型的扩展属性,setter 通常只能用于有状态的对象(如自定义类),对于不可变类(如 StringInt),setter 无法真正修改对象状态。

  • 扩展属性的调用同样依赖编译期转换,运行时性能与普通静态方法调用一致。

扩展属性是对扩展函数的补充,它让代码在保持简洁的同时,拥有更接近原生属性的调用体验。

3.扩展函数的示例

kotlin 复制代码
// 为 String 类添加扩展方法
fun String.isEmail(): Boolean {
    val emailRegex = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$".toRegex()
    return matches(emailRegex)
}

fun String.toTitleCase(): String {
    return split(" ").joinToString(" ") { 
        it.lowercase().replaceFirstChar { char -> char.uppercase() }
    }
}

// 为 String 类添加扩展属性
val String.wordCount: Int
    get() = if (isBlank()) 0 else split("\\s+".toRegex()).size

val String.firstWord: String?
    get() = split("\\s+".toRegex()).firstOrNull()

// 为 List<Int> 类添加扩展方法
fun List<Int>.sumOfEvenNumbers(): Int {
    return filter { it % 2 == 0 }.sum()
}

fun List<Int>.averageOrZero(): Double {
    return if (isEmpty()) 0.0 else average()
}

// 为 List<Int> 类添加扩展属性
val List<Int>.maxOrNull: Int?
    get() = if (isEmpty()) null else max()

val List<Int>.hasNegativeNumbers: Boolean
    get() = any { it < 0 }

fun main() {
    // 测试 String 扩展
    val text = "hello world! this is a test"
    val email = "test@example.com"
    
    println("Text in title case: ${text.toTitleCase()}")  // 扩展方法
    println("Is valid email: ${email.isEmail()}")        // 扩展方法
    println("Word count: ${text.wordCount}")             // 扩展属性
    println("First word: ${text.firstWord}")             // 扩展属性
    
    // 测试 List<Int> 扩展
    val numbers = listOf(1, 2, 3, 4, 5, 6, -1)
    
    println("\nSum of even numbers: ${numbers.sumOfEvenNumbers()}")  // 扩展方法
    println("Average (or zero): ${numbers.averageOrZero()}")         // 扩展方法
    println("Maximum value: ${numbers.maxOrNull}")                   // 扩展属性
    println("Has negative numbers: ${numbers.hasNegativeNumbers}")   // 扩展属性
}

总结:扩展特性的价值

  • 简化代码:无需继承 / 装饰者模式,就能扩展第三方库或系统类,避免类结构冗余。

  • 提升可读性 :调用方式与原生成员一致,代码更直观(如 view.show()ViewUtil.show(view) 更简洁)。

  • 无性能损耗:编译期完成转换,运行时仅执行静态方法,性能与原生代码持平。

扩展特性是 Kotlin 提升开发效率的核心手段之一,广泛用于日常开发(如 Android 中 View 的显示控制、String 的格式处理等)。

相关推荐
死就死在补习班19 分钟前
Android系统源码分析Input - InputReader读取事件
android
死就死在补习班19 分钟前
Android系统源码分析Input - InputChannel通信
android
死就死在补习班20 分钟前
Android系统源码分析Input - 设备添加流程
android
死就死在补习班21 分钟前
Android系统源码分析Input - 启动流程
android
tom4i1 小时前
Launcher3 to Launchpad 01 布局修改
android
雨白1 小时前
OkHttpClient 核心配置详解
android·okhttp
淡淡的香烟1 小时前
Android auncher3实现简单的负一屏功能
android
RabbitYao2 小时前
Android 项目 通过 AndroidStringsTool 更新多语言词条
android·python
RabbitYao2 小时前
使用 Gemini 及 Python 更新 Android 多语言 Excel 文件
android·python
纽马约2 小时前
Android RxJava的使用
android