扩展属性是类的扩展,它允许在没有添加状态(后备字段)的情况下添加getter和setter。在Java中没有这种可能性,类似的功能需要编写工具方法。从历史上看,为了添加功能,通常需要使用静态方法或包装对象。
问题:在外部类中往往缺少所需的属性。希望以简洁和安全的方式扩展类,而不破坏封装性。
解决方案:在Kotlin中,可以声明一个扩展属性,它看起来像一个普通属性,但实际上是以函数的形式实现的。这使我们能够以方便的方式扩展我们无法访问源代码的类型。
示例代码:
val String.firstChar: Char get() = this[0] println("Kotlin".firstChar) // K
关键特性:
可以在扩展属性中添加后备字段(状态)吗?
不可以,扩展属性仅在运行时计算值,不能保存状态。
扩展属性可以重写继承类中的属性吗?
不可以,扩展属性(如扩展函数)在本质上是静态的:它们不能被重写或视为虚拟的。
扩展属性是如何编译的,为什么它不是普通属性的语法等价物?
扩展属性实际上编译成静态getter(和/或setter)函数。它们不包含在类的实体中,只在声明的文件上下文中可见。
负面案例
开发者试图为Android标准View添加一个扩展属性来保存“访问”状态:
var View.isVisited: Boolean get() = ... set(value) { ... } // 错误:没有存储
优点:
缺点:
积极案例
为String实现扩展属性以获取扩展格式:
val String.asTitle: String get() = this.replaceFirstChar { it.uppercase() }
优点:
缺点: