Data Class
data class
是 kotlin
中的特殊类, 其特殊性表现在以下几个方面:
data class
的主构造函数至少需要一个参数;主构造函数的所有参数都必须使用
val
或var
修饰;data class
不能是抽象的,open
的,sealed
或内部类, 也就是说data class
只能是final
的;在
kotlin 1.1
之前,data class
还只能实现接口, 不能继承类.kotlin 1.1
之后,data class
可以继承其他类
在开发过程中, 我们经常需要使用一些类, 这些类的作用仅仅是用来存放数据, 而没有多余的函数. kotlin
中的 data class
正是为了这样的作用而存在的.
以下是一个简单的 data class
, 该类表示在二维平面中的一个点:
// kotlin
data class Point(val x: Double, val y: Double)
由于
data class
要求主构造函数至少要有一个参数 (第 1 点) , 且所有参数都必须使用val
或var
修饰 (第 2 点), 而在主构造函数中使用val
或var
修饰参数是kotlin
创建类属性的简洁写法, 因此Point
类相当于有两个属性x
,y
.调用
Point
构造函数时, 必须传递所有的参数x
,y
. 如果想为Point
类添加默认构造函数, 则需要添加辅助构造函数 (secondary constructor
):data class Point(val x: Double, val y: Double) { constructor() : this(0.0, 0.0) }
如果不想这么麻烦, 最好的办法是给主构造函数的参数添加默认值:
data class Point(val x: Double = 0.0, val y: Double = 0.0)
拷贝函数 - copy
前面说过, data class
是存放数据的类, 那么操作数据的时候就可能需要对数据进行拷贝, kotlin
默认为 data class
生成了拷贝函数 copy
. 简单调用 copy
函数将会产生一个和原来对象具有一样属性值的新对象:
val point = Point(1.0, 1.0) // (1.0, 1.0)
val point2 = point.copy() // (1.0, 1.0)
如果想在拷贝的时候做一些修改, 可以直接给 copy
函数添加参数值, 使用命名参数列表的形式:
val point = Point(1.0, 1.0) // (1.0, 1.0)
val point2 = point.copy() // (1.0, 1.0)
val point3 = point.copy(y = 3.0) // (1.0, 3.0)
componentN()
函数
除了 copy
函数, kotlin
还为 data class
生成 componentN()
函数, 其中 N
表示该 data class
的第 N
个属性. 这使得在解构 data class
对象的时候非常方便, 可以使用 (com1, com2) = dataObject
将 dataObject
的两个属性分别赋值给 com1
和 com2
:
val point = Point(1.0, 3.0)
val (x, y) = point // x = 1.0, y = 3.0
Kotlin 中的集合类 Map
的元素类型是 Map.Entry<K, V>
, 但 Kotlin 本身类库使用扩展函数 (Extension) 给 Map.Entry<K, V>
添加了 component1()
, component2()
函数, 使得在遍历 Map
时可以解构 Map.Entry<K, V>
:
mapOf(1 to "one").forEach {(key, value) -> println("$key -> $value")}
Kotlin 标准库中的 data class
在 Kotlin 类库中已经为我们提供了表示二元组的类 Pair
, 表示三元组的 Triple
, 它们的属性名分别是 first
, second
, third
. 大多数情况下使用这两个类或许已经足够, 但有时候也需要我们自己编写 data class
, 使用更符合使用场景的类名和属性名, 增强代码可读性.