0Pricing
Kotlin Academy · 课时

扩展函数:语法与分派规则

编写扩展函数,并理解静态分派语义。

扩展函数:语法与分派规则 是 CoddyKit 上的免费 Kotlin Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Kotlin Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Kotlin Academy 课程共包含 4 节课。

什么是扩展函数

扩展函数可以在不修改现有类或使用继承的情况下,向现有类添加新函数。

扩展函数的基本语法

在函数名称前加上要扩展的类型,这个类型称为“接收者类型”。
fun String.shout(): String = uppercase() + "!"
println("hello".shout())  // HELLO!
fun Int.isEven() = this % 2 == 0
println(4.isEven())  // true

扩展函数中的接收者对象

在扩展函数内部,接收者对象指代当前接收者。
fun List<Int>.secondOrNull(): Int? {
    return if (size >= 2) this[1] else null
}
println(listOf(10, 20, 30).secondOrNull())  // 20
println(listOf(5).secondOrNull())           // null

静态分派:扩展函数不会重写

扩展函数会在编译时根据声明类型进行静态解析——它们不是 NOT 虚函数。
open class Base
class Child : Base()
fun Base.greet() = "Hello from Base"
fun Child.greet() = "Hello from Child"

val obj: Base = Child()
println(obj.greet())  // "Hello from Base" (static dispatch!)

扩展函数与成员函数

如果某个类具有与扩展函数签名相同的成员函数,则始终优先调用成员函数。
class Greeter {
    fun hello() = "member hello"
}
fun Greeter.hello() = "extension hello"  // shadowed!
println(Greeter().hello())  // "member hello"

可空接收者扩展

您可以扩展可空类型。在函数内部,请通过检查接收者是否为空来处理空值。
fun String?.orEmpty() = this ?: ""
fun Any?.toStringSafe() = this?.toString() ?: "null"
println(null.orEmpty())  // ""
println(42.toStringSafe())  // "42"

可见性与作用域

扩展可以位于顶层(全局范围)、类中(成员扩展)或文件中。它们遵循常规的可见性规则。
// Top-level extension:
fun List<String>.joinUppercase() = joinToString { it.uppercase() }
// Private to file:
private fun String.clean() = trim().lowercase()

伴生对象扩展

向伴生对象添加扩展,以扩展类级别的命名空间。
class User(val name: String) {
    companion object
}
fun User.Companion.guest() = User("Guest")
val guest = User.guest()

标准库类型上的扩展

您可以扩展任何类型,包括内置类型。
fun Double.roundTo(decimals: Int): Double {
    val factor = Math.pow(10.0, decimals.toDouble())
    return Math.round(this * factor) / factor
}
println(3.14159.roundTo(2))  // 3.14

组织扩展

请将某个类型的扩展集中到专用文件中,例如 StringExtensions.kt、DateExtensions.kt。
// StringExtensions.kt
fun String.titleCase() = split(" ")
    .joinToString(" ") {
        it.replaceFirstChar { c -> c.uppercase() }
    }
println("hello world".titleCase())  // Hello World

扩展无法访问私有成员

扩展只能访问公共成员和内部成员,无法访问私有成员或受保护成员。
class Secret {
    private val key = "hidden"
    val name = "public"
}
fun Secret.reveal() {
    println(name)  // OK
    // println(key)  // Error: key is private
}

快速检查

如果类成员函数和扩展函数具有相同的签名,会调用哪一个?

回顾

扩展函数可以在不修改类的情况下向任何类添加行为。它们采用静态分派(不会重写)。成员函数优先于扩展函数。请使用可空接收者来编写空值安全的辅助函数。下一步:扩展属性!

常见问题解答

「扩展函数:语法与分派规则」课时是免费的吗?

是的 — 「扩展函数:语法与分派规则」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Kotlin Academy 课程的其余内容,请升级到 CoddyKit PRO。 Kotlin Academy 课程共包含 4 节课。

「扩展函数:语法与分派规则」这节课中我会学到什么?

编写扩展函数,并理解静态分派语义。 你通过在浏览器中直接运行的动手代码来练习 Kotlin Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Kotlin Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Kotlin Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「扩展函数:语法与分派规则」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Kotlin Academy 课中编写并运行代码吗?

能。每节 Kotlin Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 扩展函数:语法与分派规则
  2. 扩展属性与计算扩展
  3. 作用域扩展与伴生对象扩展
  4. 实用扩展:Context、View 与 String 辅助函数
← 返回 Kotlin Academy