學習 Kotlin 03 - Data Class
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
, 使用更符合使用場景的類名和屬性名, 增強程式碼可讀性.