简介
数据类在 Kotlin 中主要用于存储数据。当你需要定义一个对象来保存一些属性值时,使用数据类会非常方便。它会自动生成一些基本的方法,比如 equals()、hashCode()、toString() 和 copy() 方法。
定义数据类
定义一个数据类只需要在 class 关键字之前加上 data 关键字即可。例如:
data class Person(val name: String, val age: Int)
上述代码将创建一个名为 Person 的数据类,该类有两个属性:name 和 age。
自动生成的方法
- equals() 和 hashCode(): 这些方法基于所有属性值进行比较。
- toString(): 返回一个格式化的字符串,内容为类名和所有属性值。
- copy(): 允许你复制一个对象并修改其中的某些属性值。
- componentN(): 生成用于解构声明的函数,这些函数的数量与属性数量相同。例如,对于上述的
Person类,会有component1()和component2()方法,分别返回name和age属性。
使用示例
// www.javascriptcn.com code example
fun main() {
val alice = Person("Alice", 30)
println(alice) // 输出: Person(name=Alice, age=30)
val bob = alice.copy(name = "Bob")
println(bob) // 输出: Person(name=Bob, age=30)
val (name, age) = alice
println("Name: $name, Age: $age") // 输出: Name: Alice, Age: 30
}注意事项
- 数据类不能继承其他类,因为其构造函数参数是公开的。
- 数据类不能实现接口,因为它的所有成员都是
final的。 - 所有属性都应该是
val类型,因为数据类不允许修改其状态。
密封类
简介
密封类是一种特殊的类,它可以被子类化,但所有子类必须在同一个文件中定义。这使得它们非常适合于表示有限的、已知的类型集合。
定义密封类
密封类使用 sealed 关键字定义。例如:
sealed class Result {
data class Success(val data: Any) : Result()
data class Failure(val error: Exception) : Result()
}上述代码定义了一个名为 Result 的密封类,它有两个子类:Success 和 Failure。
使用密封类
密封类通常用于模式匹配,例如使用 when 表达式。例如:
// www.javascriptcn.com code example
fun handleResult(result: Result) {
when (result) {
is Result.Success -> println("Success: ${result.data}")
is Result.Failure -> println("Failure: ${result.error.message}")
}
}
fun main() {
val successResult = Result.Success("Hello, world!")
val failureResult = Result.Failure(Exception("Something went wrong"))
handleResult(successResult)
handleResult(failureResult)
}特点
- 密封类的所有子类必须在同一个文件中定义。
- 密封类不能在其他地方实例化,只能通过其子类。
- 密封类可以有效地模拟枚举类的行为,但提供了更多的灵活性,因为它可以有多个实例。
注意事项
- 密封类通常用于表示有限的、已知的结果集,因此非常适合于处理响应式编程中的异步操作。
- 要小心不要过度使用密封类,因为如果子类过多或逻辑复杂,可能会导致代码难以维护。
通过理解数据类和密封类,你可以更好地利用 Kotlin 的强大功能来构建高效且易于维护的应用程序。