1.3 Kotlin 特有语法糖
1.3.1 数据类(Data Class)
核心价值:简化数据模型的定义,自动生成常用方法。
kotlin
// 数据类定义
data class User(
val id: Int,
val name: String,
val email: String,
val age: Int = 0 // 默认值
)
// 创建实例
val user1 = User(1, "张三", "zhang@example.com", 25)
val user2 = User(2, "李四", "li@example.com", 30)
// 自动生成的 toString()
println(user1) // 输出:User(id=1, name=张三, email=zhang@example.com, age=25)
// 自动生成的 equals() 和 hashCode()
val user3 = User(1, "张三", "zhang@example.com", 25)
println(user1 == user3) // 输出:true(值比较)
// copy() 方法 - 创建副本并修改部分属性
val user4 = user1.copy(age = 26)
println(user4) // 输出:User(id=1, name=张三, email=zhang@example.com, age=26)
// 解构声明
val (id, name, email, age) = user1
println("ID: $id, Name: $name, Email: $email, Age: $age")
数据类的使用场景:
- API 响应数据模型
- 数据库实体类
- 配置对象
- 任何只需要存储数据的类
1.3.2 密封类(Sealed Class)
核心价值:表示受限的类继承结构,编译器知道所有子类。
kotlin
// 密封类定义
sealed class Result
data class Success(val data: String) : Result()
data class Error(val message: String) : Result()
object Loading : Result() // 单例对象
// 使用 when 表达式(智能转换)
fun handleResult(result: Result) {
when (result) {
is Success -> println("成功:${result.data}")
is Error -> println("错误:${result.message}")
is Loading -> println("加载中...")
// 不需要 else 分支,编译器知道所有可能性
}
}
// 使用
val result1: Result = Success("数据加载成功")
handleResult(result1) // 输出:成功:数据加载成功
val result2: Result = Error("网络连接失败")
handleResult(result2) // 输出:错误:网络连接失败
val result3: Result = Loading
handleResult(result3) // 输出:加载中...
密封类的使用场景:
- 表示有限的状态(如 UI 状态)
- 处理网络请求结果
- 定义受限的类型系统
- 表达式的模式匹配
1.3.3 对象表达式与单例
单例对象:
kotlin
// 单例对象
object DatabaseConfig {
const val DATABASE_NAME = "my_app.db"
const val DATABASE_VERSION = 1
fun getConnection(): String {
return "jdbc:sqlite:$DATABASE_NAME"
}
}
// 使用
DatabaseConfig.getConnection() // 输出:jdbc:sqlite:my_app.db
DatabaseConfig.DATABASE_NAME // 输出:my_app.db
伴生对象(Companion Object):
kotlin
class UserFactory {
companion object {
private const val DEFAULT_AGE = 18
fun create(name: String): User {
return User(0, name, "", DEFAULT_AGE)
}
fun createWithId(id: Int, name: String): User {
return User(id, name, "", DEFAULT_AGE)
}
}
}
// 使用(类似 Java 的静态方法调用)
val user1 = UserFactory.create("张三")
val user2 = UserFactory.createWithId(1, "李四")
对象表达式(匿名内部类的替代):
kotlin
// Java 风格的匿名内部类
button.setOnClickListener(object : OnClickListener {
override fun onClick(view: View) {
println("按钮被点击")
}
})
// Lambda 表达式(更简洁)
button.setOnClickListener { view ->
println("按钮被点击")
}
// SAM 转换(Single Abstract Method)
button.setOnClickListener { println("按钮被点击") }
1.3.4 扩展函数与属性
核心价值:在不修改原有类的情况下,为类添加新的方法。
kotlin
// 扩展函数
fun String.lastChar(): Char {
return this[this.length - 1]
}
// 使用
val name = "Kotlin"
println(name.lastChar()) // 输出:n
// 扩展属性
val String.lastIndex: Int
get() = this.length - 1
// 使用
println("Hello".lastIndex) // 输出:4
// 扩展函数用于 Android View
fun View.gone() {
this.visibility = View.GONE
}
fun View.visible() {
this.visibility = View.VISIBLE
}
fun View.invisible() {
this.visibility = View.INVISIBLE
}
// 使用
textView.gone()
button.visible()
实际应用场景:
kotlin
// 扩展函数简化日期格式化
fun Date.toFormattedString(): String {
val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
return sdf.format(this)
}
// 使用
val currentDate = Date()
println(currentDate.toFormattedString())
// 扩展函数简化 SharedPrefences 操作
fun SharedPreferences.putBoolean(key: String, value: Boolean) {
edit().putBoolean(key, value).apply()
}
fun SharedPreferences.getBoolean(key: String, defaultValue: Boolean): Boolean {
return getBoolean(key, defaultValue)
}
// 使用
val prefs = getSharedPreferences("app_prefs", Context.MODE_PRIVATE)
prefs.putBoolean("is_logged_in", true)
val isLoggedIn = prefs.getBoolean("is_logged_in", false)