轉向Kotlin——數據類和封閉類

數據類和封閉類是Kotlin中的兩種特殊的類,今天一塊兒瞭解一下。更多精彩內容也能夠關注個人微信公衆號——Android機動車數據庫

數據類

數據類是Kotlin的一個語法糖。Kotlin編譯器會自動爲數據類生成一些成員函數,以提升開發效率。bash

數據類的使用

不管是Java服務器開發仍是Android開發,實體類天然是特別熟悉,它就是將Json格式轉化爲一個只包含數據和基本操做方法的實體類,以方便網絡存取和數據庫存取。服務器

咱們老是須要一個類來表示數據,例如要表示一個用戶的數據,咱們會建立一個User類,並經過構造器傳入兩個屬性:微信

class User(name: String, age: Int) {
    var mName = name
    var mAge: Int = age
}
複製代碼

咱們定義實體類,除了要保存數據以外,還須要輸出對象的值,比較對象等操做,前者會用到toString函數,後者會用到equals函數,以下:網絡

var user1 = User("js", 20)
var user2 = User("lx", 12)

println(user1)
println(user2)
println(user1.equals(user2))
複製代碼

輸出結果是:函數

User@3764951d
User@4b1210ee
false
複製代碼

從結果能夠看出,輸出User的兩個對象時,調用了這兩個對象的toString方法,但toString函數默認會調用hashcode函數,輸出當前對象的hashcode,並在前面加上 類名@this

對象的equals方法默認也是比較了兩個對象的hashcode,兩個對象hashcode不一樣,天然返回false。spa

有時咱們的業務需求是這樣的:打印對象,即按規則打印對象的全部屬性,兩個對象的全部屬性值相同,則返回兩個對象相等,因而乎咱們須要重寫toString函數和equals函數,相信你們都會寫,這裏就再也不累贅了。code

儘管前面寫的User類實現了咱們的需求,但會不會也太麻煩了,每一個類都須要重寫toString和equals等方法。爲了提升開發效率,Kotlin加入了咱們立刻要介紹的數據類。cdn

所謂數據類,就是隻定義必要的部分,其他部分能夠自動生成。

從上面的類能夠看出,只有name和age是必須的,其他的都是能夠自動推導的。**數據類規定:屬性要經過主構造器指定,並且還要在class關鍵字以前加data。**咱們再寫一個數據類,以下:

data class Person(var name: String, val age: Int)
複製代碼

能夠看出,本來十幾行幾十行的代碼,如今一行就搞定了,其他的Kotlin編譯器會自動生成。

數據類也和普通類同樣,也能夠繼承其餘類,有一些其餘的成員函數等。

編寫一個數據類須要注意:

  • 主構造器至少要有一個參數;
  • 主構造器的參數要用var或val修飾;
  • 數據類不能是抽象類、open類、封閉類或者內部類。

因爲主構造器中必須至少要有一個參數,因此在數據類中,不可能存在無參的主構造器,要想讓數據類擁有一個無參的構造器,有如下兩種方法:

  1. 爲主構造器的每個參數都加上默認值;
  2. 添加一個沒有參數的次構造器,並調用主構造器同時指定各參數。
data class MPerson(var name: String = "js", var age: Int = 20)

data class NPerson(var name: String, var age: Int) {
    // 次構造器,this調用主構造器,並指定參數
    constructor() : this("js", 20)
}
複製代碼

對象的複製

在開發中,咱們常常須要複製一個對象,而後修改它的一部分屬性,這就須要複製機制,Kotlin除了爲數據類自動生成toString方法和equals方法,還默認生成了一個copy方法,它的做用就是複製數據類的實例。代碼以下:

var person = Person("wj", 20)
var mCopyPerson1 = person.copy()
var mCopyPerson2 = person.copy(name = "js")
複製代碼

數據類成員的解構

所謂解構,就是解除結構,指的是將數據對象中的屬性提取出來,分別賦給單個變量。

Kotlin編譯器會自動爲數據類生成組件函數(之後會說到),所以,能夠直接將數據類成員解構:

var js = Person("Js", 20)
// 將js.name和js.age分別賦給name和age變量
var (name, age) = js
println("$name, is $age years old")
複製代碼

封閉類

封閉類能夠看做是枚舉的擴展。一個封閉類,前面用sealed關鍵字標識。能夠有任意多個子類和對象。封閉類的值只能是這些子類和對象。

使用封閉類的好處是when表達式,不須要再使用else形式了。看個例子:

sealed class Expr

data class Const(var count: Int) : Expr()
data class Sun(var e1: Expr, var e2: Expr) : Expr()

fun evel(expr: Expr): Int = when (expr) {
    is Const -> expr.count
    is Sun -> evel(expr.e1) + evel(expr.e2)
}
複製代碼

總結

在Kotlin中提供了一些特殊的類,其中數據類和封閉類就是其中的兩個。儘管這些特殊的類並非必須的,但有些時候使用它們會給咱們的開發帶來很大的方便,尤爲是數據類。

更多精彩內容,歡迎關注個人微信公衆號——Android機動車

這裏寫圖片描述
相關文章
相關標籤/搜索