
如果你也像我一樣,喜歡懶惰而又高效,那么數(shù)據(jù)類就是你需要了解的一種特殊類型的類。
數(shù)據(jù)類可以用于存儲(chǔ)數(shù)據(jù)而不必關(guān)心那些煩人的業(yè)務(wù)邏輯。而且,Kotlin編譯器會(huì)自動(dòng)為你生成equals()、hashCode()和toString()等方法,你再也不用像定義javaBean那樣去編寫(xiě)它們了,省時(shí)省力,wonderful。
數(shù)據(jù)類的定義
定義一個(gè)數(shù)據(jù)類非常簡(jiǎn)單,只需要在類前面添加一個(gè)data關(guān)鍵字即可,就像這樣:
kotlin
data class User(val name: String, val age: Int)
上述示例定義了一個(gè)名為User的數(shù)據(jù)類,它有兩個(gè)屬性:name和age,它們都是不可變的(使用val關(guān)鍵字)。同時(shí),編譯器也會(huì)為你自動(dòng)生成一些好用的方法,例如equals()、hashCode()、toString()和copy()等。
解構(gòu)聲明
我們可以使用解構(gòu)聲明來(lái)訪問(wèn)數(shù)據(jù)類的屬性。這聽(tīng)起來(lái)有點(diǎn)高端大氣上檔次,但實(shí)際上非常簡(jiǎn)單。例如:
kotlin
val user = User("Alice", 30) val (name, age) = user println("$name, $age years of age")
上述示例創(chuàng)建了一個(gè)User對(duì)象,并使用解構(gòu)聲明將name和age屬性的值分別賦給了name和age變量。這樣,我們就可以輕松愉快地訪問(wèn)數(shù)據(jù)類的屬性了。
拷貝數(shù)據(jù)類對(duì)象
如果你曾經(jīng)為了創(chuàng)建一個(gè)數(shù)據(jù)類的副本而頭禿,什么深拷貝淺拷貝弄不清,那么copy()方法就是你的救星了。使用它,你可以輕松創(chuàng)建一個(gè)數(shù)據(jù)類的副本,例如:
kotlin
val user = User("Alice", 30)
val olderUser = user.copy(age = user.age + 1)
上述示例創(chuàng)建了一個(gè)User對(duì)象,并使用copy()方法創(chuàng)建了一個(gè)新對(duì)象,其中age屬性的值增加了1。爽歪歪!
另外,注意,如果屬性是一個(gè)對(duì)象,這時(shí)候拷貝是淺拷貝哦,需要自己實(shí)現(xiàn)深拷貝,再傳進(jìn)去。
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)
//會(huì)看到persion1和persion2的address打印出來(lái)的引用時(shí)一樣的
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)
}
數(shù)據(jù)類的限制
數(shù)據(jù)類是一種非常神奇的類,但也有一些限制。這包括:
- 數(shù)據(jù)類不能是抽象的、開(kāi)放的(就是不能被繼承,保持?jǐn)?shù)據(jù)獨(dú)立性)、密封的或內(nèi)部的。
- 數(shù)據(jù)類必須至少有一個(gè)主要構(gòu)造函數(shù),且該構(gòu)造函數(shù)中的參數(shù)必須標(biāo)記為
val或var。 - 數(shù)據(jù)類不能在主體中定義
equals()、hashCode()或toString()等方法,否則編譯器將報(bào)錯(cuò)。 - 數(shù)據(jù)類的屬性必須是
public或internal,不能是private或protected(擱著保密呢)。
總結(jié)
Kotlin數(shù)據(jù)類是一種非常有用、簡(jiǎn)單和方便的類類型。它們?yōu)槲覀兲峁┝艘环N快速而簡(jiǎn)便的方式來(lái)存儲(chǔ)數(shù)據(jù),而不必為每個(gè)類編寫(xiě)大量的模板代碼。
此外,數(shù)據(jù)類還提供了許多好用的方法,例如equals()、hashCode()和toString()等。你可以使用它們來(lái)方便地比較和打印對(duì)象。
最后,不要忘記數(shù)據(jù)類的一些限制哦。