剛開始看到 data class A... 這種寫法時,感覺比較怪,了解之后,發(fā)現(xiàn)是對一些只處理數(shù)據(jù)的類的一種語法糖。
kotlin中所有的類都繼承自 Any 類,這個就相當(dāng)于js中的 Object. Any 類有3個通用的方法:
public open class Any {
public open operator fun equals(other: Any?): Boolean
public open fun hashCode(): Int
public open fun toString(): String
}
而 data class 對上面的3個方法進(jìn)行了override,并且提供了一些其他便利的功能
相等性 (== 和 ===)
相等性data class, 可以使用 == 來比較2個實例是否數(shù)據(jù)上是一致的, === 可以用來比較,引用關(guān)系是否是一致的
data class Dog(val name: String, val color: String) {}
val d1 = Dog("Lisa", "white")
val d2 = Dog("Lisa", "white")
// 數(shù)據(jù)上是否是一樣的
print("${d1 == d2}") // true
// 引用上是否是一致的
print("${d1 === d2}") // false
有一點需要注意的是,數(shù)據(jù)上是否是一致的,只能比較主構(gòu)造器中的屬性是否相同,data class 其它的屬性不參與比較
data class Dog(val name: String, val color: String) {
val food: String = ""
}
val d1 = Dog("Lisa", "white")
d1.food = "beef"
val d2 = Dog("Lisa", "white")
d2.food = "pork"
// 數(shù)據(jù)上是否是一樣的
// 只比較 name color 屬性是否相同
print("${d1 == d2}") // true 仍然是相等的
copy() 方法
對數(shù)據(jù)進(jìn)行拷貝操作提供了便利
data class Dog(val name: String, val color: String) {}
val d1 = Dog("Lisa", "white")
val d2 = d1.copy() // 直接進(jìn)行數(shù)據(jù)拷貝
print("${d1 == d2}") // true
print("${d1 === d2}") // false
// 另外拷貝時還可以對數(shù)據(jù)進(jìn)行修改
val d3 = d1.copy(color = "yellow")
print("${d3.toString()}") // Dog(name="Lisa",color="yellow")
print("${d1.toString()}") // Dog(name="Lisa",color="white") d1不能受到影響
val d4 = d1.copy(name="Tommy", color="gold")
componentN 函數(shù) 和 解構(gòu)
這個是對屬性訪問的一種便利方式
data class Dog(val name: String, val color: String) {}
val d1 = Dog("Lisa", "white")
// 獲取屬性的方式
val name = d1.name
val color = d2.color
// 等價于
val name = d1.component1()
val color = d2.component2()
// 因為有了componentN方法,data class可以使用解構(gòu)
// 解構(gòu)的方式和js中的解構(gòu)類似
val (name, color) = d1
非 data class 是不能使用解構(gòu)的
使用data class 需要注意的地方
- 主構(gòu)造器必須要有一個參數(shù),參數(shù)必須使用 var 或者 val 定義
- 數(shù)據(jù)類不能有以下修飾符: abstract,inner,open,sealed