系列文章全部為本人的學(xué)習(xí)筆記奸柬,若有任何不妥之處偎捎,隨時(shí)歡迎拍磚指正鹉梨。如果你覺得我的文章對你有用讳癌,歡迎關(guān)注我,我們一起學(xué)習(xí)進(jìn)步存皂!
Kotlin學(xué)習(xí)筆記(1)- 環(huán)境配置
Kotlin學(xué)習(xí)筆記(2)- 空安全
Kotlin學(xué)習(xí)筆記(3)- 語法
Kotlin學(xué)習(xí)筆記(4)- 流程控制
Kotlin學(xué)習(xí)筆記(5)- 類
Kotlin學(xué)習(xí)筆記(6)- 屬性
Kotlin學(xué)習(xí)筆記(7)- 接口
Kotlin學(xué)習(xí)筆記(8)- 擴(kuò)展
Kotlin學(xué)習(xí)筆記(8)- 擴(kuò)展(續(xù))
Kotlin學(xué)習(xí)筆記(9)- 數(shù)據(jù)類
Kotlin學(xué)習(xí)筆記(10)- 泛型
Kotlin學(xué)習(xí)筆記(11)- 內(nèi)部類和嵌套類
Kotlin學(xué)習(xí)筆記(12)- 委托
Kotlin學(xué)習(xí)筆記(13)- 函數(shù)式編程
Kotlin學(xué)習(xí)筆記(14)- lambda
這些天項(xiàng)目比較忙晌坤,一直在加班,現(xiàn)在周末了旦袋,趕緊把kotlin拿起來骤菠,繼續(xù)學(xué)習(xí)~
一、定義
在平時(shí)的使用中疤孕,我們會用到一些類來保持一些數(shù)據(jù)或狀態(tài)商乎,我們習(xí)慣上成為bean
或者entity
,也有的定義為model
祭阀。kotlin中有專門處理這一種類的關(guān)鍵字:data鹉戚。
data class PersonData(var name : String, var age : Int)
這種由data修飾的類叫做數(shù)據(jù)類,編譯器自動(dòng)從在主構(gòu)造函數(shù)定義的全部特性中得到以下成員:
-
equals()
/hashCode()
-
toString()
格式是"PersonData(name=PersonData, age=20)"
-
componentN()
方法對應(yīng)按聲明順序出現(xiàn)的所有屬性 -
copy()
方法
如果有某個(gè)函數(shù)被明確地定義在類里或者被繼承专控,編譯器就不會生成這個(gè)函數(shù)抹凳。
上面是官方說法,換成通俗的說就是伦腐,如果在數(shù)據(jù)類里自定義了equals
等某個(gè)方法赢底,那編譯器就不會再去生成它。
總結(jié)一下柏蘑,數(shù)據(jù)類的定義就是以下幾個(gè)特點(diǎn):
- 類由關(guān)鍵字
data
修飾(好像是廢話) - 類的構(gòu)造參數(shù)必須由
var
/val
修飾幸冻,否則編譯不通過 - ?編譯器會自動(dòng)生成一些常用方法,你可以自定義它們
- 和普通類一樣咳焚,如果你需要一個(gè)無參構(gòu)造方法洽损,可以將構(gòu)造方法的參數(shù)都設(shè)置默認(rèn)值
二、toString
如果沒有自定義的話黔攒,編譯器會自動(dòng)生成toString
方法趁啸,輸出格式為類名+參數(shù)的順序值
// 定義數(shù)據(jù)類和普通類
data class PersonData(var name : String, var age : Int)
class PersonNormal(var name : String, val age : Int)
// 分別初始化并進(jìn)行toString輸出
fun test(){
var personD = PersonData("PersonData", 20)
var personN = PersonNormal("PersonNormal", 20)
Log.d("test", personD.toString())
Log.d("test", personN.toString())
}
// 輸出
PersonData(name=PersonData, age=20)
com.study.jcking.weatherkotlin.exec.PersonNormal@26b13e2
三、復(fù)制copy
copy方法可以讓我們方便的對數(shù)據(jù)類進(jìn)行賦值督惰,甚至是有修改的復(fù)制不傅。比如我們上面寫道的PersonD
,如果我們想對它進(jìn)行賦值赏胚,并且將名字改為PersonCopy
var personC = personD.copy("Person Copy")
Log.d("test", personC.toString())
//輸出
PersonData(name=Person Copy, age=20)
我們只需要傳遞我們要修改的部分访娶,編輯器會自動(dòng)識別。上面的寫法大概是這種實(shí)現(xiàn)
fun copy(name: String = this.name, age: Int = this.age) = PersonData(name, age)
如果我們的構(gòu)造參數(shù)中有多個(gè)參數(shù)類型一致觉阅,上面的寫法會按定義的順序優(yōu)先匹配
data class PersonData(var name : String, var age : Int, val sex : String)
var personD = PersonData("PersonData", 20, "male")
var personC = personD.copy("famale")
Log.d("test", personC.toString())
// 輸出
PersonData(name=famale, age=20, sex=male)
其實(shí)很明顯的崖疤,我們要修改的是sex
,也就是第三個(gè)參數(shù)典勇。這時(shí)候需要指定參數(shù)名
var personC = personD.copy(sex = "famale")
// 輸出
PersonData(name=PersonData, age=20, sex=famale)
OK劫哼,完美
四、多聲明
多聲明割笙,也可以理解為變量映射权烧,這就是編譯器自動(dòng)生成的componentN()
方法。
var personD = PersonData("PersonData", 20, "male")
var (name, age) = personD
Log.d("test", "name = $name, age = $age")
//輸出
name = PersonData, age = 20
上面的多聲明伤溉,大概可以翻譯成這樣
var name = f1.component1()
var age = f1.component2()
五般码、序列化
由于我們的項(xiàng)目中,要求所有數(shù)據(jù)類都序列化乱顾,那么在學(xué)習(xí)kotlin時(shí)自然就想到了數(shù)據(jù)類的序列化問題板祝。在Android Studio上,java的數(shù)據(jù)類可以通過Parcelable
插件自動(dòng)進(jìn)行序列化走净,kotlin中暫時(shí)不能用券时,只能自己實(shí)現(xiàn)。實(shí)現(xiàn)方法和java中的手動(dòng)實(shí)現(xiàn)基本一致伏伯。
data class PersonData(var name : String, var age : Int, val sex : String) : Parcelable{
override fun writeToParcel(p0: Parcel?, p1: Int) {
p0?.writeString(this.name)
p0?.writeInt(this.age)
p0?.writeString(this.sex)
}
override fun describeContents(): Int {
return 0
}
constructor(source: Parcel) : this(source.readString(), source.readInt(), source.readString())
companion object {
@JvmField val CREATOR: Parcelable.Creator<PersonData> = object : Parcelable.Creator<PersonData> {
override fun createFromParcel(source: Parcel): PersonData {
return PersonData(source)
}
override fun newArray(size: Int): Array<PersonData?> {
return arrayOfNulls(size)
}
}
}
}