数据类是其主要目的是保存数据的类。数据类会自动附带额外的成员方法
使用data
声明一个数据类
data class User(val name: String, val age: Int)
编译器会自动从主构造函数中声明的所有属性派生以下成员
-
.equals()
/.hashCode()
-
.toString()
如:"User(name=John, age=42)"
-
.componentN()
(在后边的文章会讲到) -
.copy()
为了确保生成的代码的一致性和有意义的行为,数据类必须满足以下要求
- 主构造函数必须至少有一个参数
- 所有主构造函数参数必须标记为
val
或var
- 数据类不能是抽象的(abstract),开放的(open)(数据类不能被继承),密封的(sealed), 或者内部的(inner)
数据类成员的生成遵循以下规则,涉及成员的继承:
- 如果在数据类中有
.equals()
、.hashCode()
或.toString()
的显式实现,或者在超类中有这些方法的最终实现,则不会生成这些方法,而是使用现有的实现 - 如果父类(超类型)有
.componentN()
方法,并且这些方法是open
的,同时返回的类型与数据类兼容,那么数据类会为这些方法生成相应的实现,并覆盖超类型的方法。如果由于不兼容返回值或者使用final
修饰而导致超类型的方法无法被覆盖,则会报告错误。 - 不允许为
.componentN()
和.copy()
方法提供显式实现。
在JVM上如果需要一个无参构造函数,需要给主构造函数的参数指定默认值
data class User(val name: String = "", val age: Int = 0)
类主体中声明的属性
编译器仅在自动生成的函数中使用主构造函数内定义的属性。要从生成的实现中排除某个属性,请将其声明在类体内
data class Person(val name: String) {
var age: Int = 0
}
在这个例子中,只有 name
属性可以在 .toString()
、.equals()
、.hashCode()
和 .copy()
的实现中使用,而且只有一个名为 .component1()
的分量函数。age
属性不能在这些实现中使用,因为它是在类体内声明的。如果两个 Person
对象具有不同的年龄但相同的名称,那么它们会被视为相等。这是因为.equals()
函数只能检查name
属性的相等性。
fun main() {
val person1 = Person("John")
val person2 = Person("John")
person1.age = 10
person2.age = 20
println("person1 == person2: ${person1 == person2}") // person1 == person2: true
println("person1 with age ${person1.age}: ${person1}") // person1 with age 10: Person(name=John)
println("person2 with age ${person2.age}: ${person2}") // person2 with age 20: Person(name=John)
}
拷贝
使用.copy()
函数来复制一个对象,允许您更改其中一些属性而保持其余部分不变。对于 User
类的.copy()
函数实现如下
data class User(val name: String = "", val age: Int = 0)
// fun copy(name: String = this.name, age: Int = this.age) = User(name, age)
fun main() {
val user = User("John")
val copy = user.copy(age = 2)
println(user) // User(name=John, age=0)
println(copy) // User(name=John, age=2)
}
数据类和解构声明
为数据类生成的分量函数(Component functions)使得可以在解构声明(destructuring declarations)中使用它们
fun main() {
val jane = User("Jane", 35)
val (name, age) = jane
println("$name, $age years of age") // Jane, 35 years of age
}
结构函数依赖于
.componentN()
方法,因此只有在主构造函数中的参数才能使用结构函数文章来源:https://www.toymoban.com/news/detail-773103.html
标准数据类
标准库提供了Pair
和Triple
类。然而,在大多数情况下,使用具有命名属性的数据类是更好的设计选择,因为它们通过为属性提供有意义的名称使代码更易读。
作者文章来源地址https://www.toymoban.com/news/detail-773103.html
到了这里,关于18:kotlin 类和对象 -- 数据类(Data classes)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!