如果你也像我一样,喜欢懒惰而又高效,那么数据类就是你需要了解的一种特殊类型的类。
数据类可以用于存储数据而不必关心那些烦人的业务逻辑。而且,Kotlin编译器会自动为你生成equals()、hashCode()和toString()等方法,你再也不用像定义javaBean那样去编写它们了,省时省力,wonderful。
数据类的定义
定义一个数据类非常简单,只需要在类前面添加一个data
关键字即可,就像这样:
kotlin
data class User(val name: String, val age: Int)
上述示例定义了一个名为User
的数据类,它有两个属性:name
和age
,它们都是不可变的(使用val
关键字)。同时,编译器也会为你自动生成一些好用的方法,例如equals()
、hashCode()
、toString()
和copy()
等。
解构声明
我们可以使用解构声明来访问数据类的属性。这听起来有点高端大气上档次,但实际上非常简单。例如:
kotlin
val user = User("Alice", 30) val (name, age) = user println("$name, $age years of age")
上述示例创建了一个User
对象,并使用解构声明将name
和age
属性的值分别赋给了name
和age
变量。这样,我们就可以轻松愉快地访问数据类的属性了。
拷贝数据类对象
如果你曾经为了创建一个数据类的副本而头秃,什么深拷贝浅拷贝弄不清,那么copy()
方法就是你的救星了。使用它,你可以轻松创建一个数据类的副本,例如:
kotlin
val user = User("Alice", 30)
val olderUser = user.copy(age = user.age + 1)
上述示例创建了一个User
对象,并使用copy()
方法创建了一个新对象,其中age
属性的值增加了1。爽歪歪!
另外,注意,如果属性是一个对象,这时候拷贝是浅拷贝哦,需要自己实现深拷贝,再传进去。
data class Person(val name: String, val age: Int, val address: Address)
class Address(var street: String, val city: String) {
fun copy(street: String = this.street, city: String = this.city) = Address(street, city)
}
fun main() {
val address = Address("123 Main St", "Anytown")
val person1 = Person("Alice", 29, address)
// 浅拷贝
val person2 = person1.copy()
// 深拷贝
val addressCopy = person1.address.copy()
val person3 = person1.copy(address = addressCopy)
//会看到persion1和persion2的address打印出来的引用时一样的
println(person1)
println(person2)
println(person3)
// 修改person1的地址,可以看到persion2的地址也改变
person1.address.street = "456 Second hehehe"
println(person1.address.street)
println(person2.address.street)
println(person3.address.street)
}
数据类的限制
数据类是一种非常神奇的类,但也有一些限制。这包括:
- 数据类不能是抽象的、开放的(就是不能被继承,保持数据独立性)、密封的或内部的。
- 数据类必须至少有一个主要构造函数,且该构造函数中的参数必须标记为
val
或var
。 - 数据类不能在主体中定义
equals()
、hashCode()
或toString()
等方法,否则编译器将报错。 - 数据类的属性必须是
public
或internal
,不能是private
或protected
(搁着保密呢)。
总结
Kotlin数据类是一种非常有用、简单和方便的类类型。它们为我们提供了一种快速而简便的方式来存储数据,而不必为每个类编写大量的模板代码。
此外,数据类还提供了许多好用的方法,例如equals()
、hashCode()
和toString()
等。你可以使用它们来方便地比较和打印对象。
最后,不要忘记数据类的一些限制哦。