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 的格式处理等)。

相关推荐
娅娅梨22 分钟前
Android- Surface, SurfaceView, TextureView, SurfaceTexture 原理图解
android·surface
2501_915918412 小时前
HTTPS 端口号详解 443 端口作用、iOS 抓包方法、常见 HTTPS 抓包工具与网络调试实践
android·网络·ios·小程序·https·uni-app·iphone
程序员码歌2 小时前
明年35岁了,如何破局?说说心里话
android·前端·后端
非门由也4 小时前
Android studio安装教程——超详细(含安装包安装教程)
android·ide·android studio
平淡风云4 小时前
Android应用添加日历提醒功能
android·日历
骐骥15 小时前
2025-09-08升级问题记录:app提示“此应用专为旧版Android打造..”或“此应用与最新版 Android 不兼容”
android·升级·不兼容·target sdk·专为旧版 android 系统
Zender Han6 小时前
Flutter 视频播放器——flick_video_player 介绍与使用
android·flutter·ios·音视频
尚久龙7 小时前
安卓学习 之 用户登录界面的简单实现
android·运维·服务器·学习·手机·android studio·安卓
Modu_MrLiu7 小时前
Android实战进阶 - 启动页
android·实战进阶·启动页·倒计时场景
出门吃三碗饭7 小时前
编译器构造:从零手写汇编与反汇编程序(一)
android·汇编