equals()
/hashCode()
toString()
格式如"User(name=John, age=42)"
componentN() functions
對(duì)應(yīng)于屬性,按聲明順序排列copy()
函數(shù)
如果這些函數(shù)在類中已經(jīng)被明確定義了,或者從超類中繼承而來,就不再會(huì)生成。
為了保證生成代碼的一致性以及有意義,數(shù)據(jù)類需要滿足以下條件:
主構(gòu)造函數(shù)至少包含一個(gè)參數(shù)。
所有的主構(gòu)造函數(shù)的參數(shù)必須標(biāo)識(shí)為
val
或者var
;數(shù)據(jù)類不可以聲明為
abstract
,open
,sealed
或者inner
;數(shù)據(jù)類不能繼承其他類 (但是可以實(shí)現(xiàn)接口)。
復(fù)制
復(fù)制使用 copy() 函數(shù),我們可以使用該函數(shù)復(fù)制對(duì)象并修改部分屬性, 對(duì)于上文的 User 類,其實(shí)現(xiàn)會(huì)類似下面這樣:
fun copy(name: String = this.name, age: Int = this.age) = User(name, age)
實(shí)例
使用 copy 類復(fù)制 User 數(shù)據(jù)類,并修改 age 屬性:
data class User(val name: String, val age: Int)fun main(args: Array<String>) { val jack = User(name = "Jack", age = 1) val olderJack = jack.copy(age = 2) println(jack) println(olderJack)}
輸出結(jié)果為:
User(name=Jack, age=1)User(name=Jack, age=2)
數(shù)據(jù)類以及解構(gòu)聲明
組件函數(shù)允許數(shù)據(jù)類在解構(gòu)聲明中使用:
val jane = User("Jane", 35)val (name, age) = jane println("$name, $age years of age") // prints "Jane, 35 years of age"
標(biāo)準(zhǔn)數(shù)據(jù)類
標(biāo)準(zhǔn)庫提供了 Pair 和 Triple 。在大多數(shù)情形中,命名數(shù)據(jù)類是更好的設(shè)計(jì)選擇,因?yàn)檫@樣代碼可讀性更強(qiáng)而且提供了有意義的名字和屬性。
密封類
密封類用來表示受限的類繼承結(jié)構(gòu):當(dāng)一個(gè)值為有限幾種的類型, 而不能有任何其他類型時(shí)。在某種意義上,他們是枚舉類的擴(kuò)展:枚舉類型的值集合 也是受限的,但每個(gè)枚舉常量只存在一個(gè)實(shí)例,而密封類 的一個(gè)子類可以有可包含狀態(tài)的多個(gè)實(shí)例。
聲明一個(gè)密封類,使用 sealed 修飾類,密封類可以有子類,但是所有的子類都必須要內(nèi)嵌在密封類中。
sealed 不能修飾 interface ,abstract class(會(huì)報(bào) warning,但是不會(huì)出現(xiàn)編譯錯(cuò)誤)
sealed class Exprdata class Const(val number: Double) : Expr()data class Sum(val e1: Expr, val e2: Expr) : Expr()object NotANumber : Expr()fun eval(expr: Expr): Double = when (expr) { is Const -> expr.number is Sum -> eval(expr.e1) + eval(expr.e2) NotANumber -> Double.NaN}
使用密封類的關(guān)鍵好處在于使用 when 表達(dá)式 的時(shí)候,如果能夠 驗(yàn)證語句覆蓋了所有情況,就不需要為該語句再添加一個(gè) else 子句了。
fun eval(expr: Expr): Double = when(expr) { is Expr.Const -> expr.number is Expr.Sum -> eval(expr.e1) + eval(expr.e2) Expr.NotANumber -> Double.NaN // 不再需要 `else` 子句,因?yàn)槲覀円呀?jīng)覆蓋了所有的情況}
xinyuli
org***126.com
參考地址
我的理解密封類就是一種專門用來配合 when 語句使用的類,舉個(gè)例子,假如在 Android 中我們有一個(gè) view,我們現(xiàn)在想通過 when 語句設(shè)置針對(duì) view 進(jìn)行兩種操作:顯示和隱藏,那么就可以這樣做:
以上功能其實(shí)完全可以用枚舉實(shí)現(xiàn),但是如果我們現(xiàn)在想加兩個(gè)操作:水平平移和縱向平移,并且還要攜帶一些數(shù)據(jù),比如平移了多少距離,平移過程的動(dòng)畫類型等數(shù)據(jù),用枚舉顯然就不太好辦了,這時(shí)密封類的優(yōu)勢(shì)就可以發(fā)揮了,例如:
以上代碼中,TranslateX 是一個(gè)類,它可以攜帶多于一個(gè)的信息,比如除了告訴 view 需要水平平移之外,還可以告訴 view 平移多少像素,甚至還可以告訴 view 平移的動(dòng)畫類型等信息,我想這大概就是密封類出現(xiàn)的意義吧。
除此之外,如果 when 語句的分支不需要攜帶除“顯示或隱藏view之外的其它信息”時(shí)(即只需要表明 when 語句分支,不需要攜帶額外數(shù)據(jù)時(shí)),用 object 關(guān)鍵字創(chuàng)建單例就可以了,并且此時(shí) when 子句不需要使用 is 關(guān)鍵字。只有需要攜帶額外信息時(shí)才定義密封類的子類,而且使用了密封類就不需要使用 else 子句,每當(dāng)我們多增加一個(gè)密封類的子類或單例,編譯器就會(huì)在 when 語句中給出提示,可以在編譯階段就及時(shí)發(fā)現(xiàn)錯(cuò)誤,這也是以往 switch-case 語句和枚舉不具備的功能。
最后,我們甚至可以把這一組操作封裝成一個(gè)函數(shù),以便日后調(diào)用,如下: