Kotlin構造方法梳理

Kotlin主從構造方法梳理

1. 主構造方法

​ Kotlin中有個專有名詞叫做主構造方法(primary construcor),其實很好理解,但弄清楚這個詞是理清Kotlin中構造方法的前提。所謂主構造方法,就是在類定義的第一行的類名後面添加( ),即以類名加括號的表達方式來表示主構造方法。

	class User(val name: String = “Bob") {
    ...
  }

2. 兩種構造方式

​ Kotlin中的構造方式可以歸納爲兩類:

  1. 單一個主構造方法

    這種構造包含Java中構造方法的兩種形式

    • 只有一個構造方法
    • 多個重載參數的的構造方法

    通過在主構造方法中添加參數,可以自動在類中添加相應的屬性和默認值,這種方式可以以簡單的方式實現Java中需要多個構造方法重載接受多個參數的用例,可以涵蓋大部分曾經需要多個構造方法的情形。當主構造方法中每一個參數都存在默認值時,會自動生成無參的構造方法。

  2. 有多個並列的構造方法

    上述構造方式雖然涵蓋了大部分我們需要重載構造方法的情形,但當我們需要根據不同的參數提供不同的初始化方法時我們需要提供完整的構造方法。Kotlin提供了多個並列的構造方法的形式來滿足這種需求:

    	class User{
        constructor(name: String) {
          ...
        }
        
        constructor(id: Long) {
          ...
        }
      }
    

    與主構造方法相應的,我們將使用constructor的構造方法稱爲從構造方法(secondary constructor),注意在這種構造方式中,我們不能在constructor的參數中通過val或var來爲類添加相應的屬性。使用這種構造方式就與Java中的構造方法頗爲類似了,只不過我們用constructor關鍵字取代了類名。

no
yes
是否根據參數提供不同初始化方式?
單一主構造方法
多個並列構造方法

3. 一主多從的構造方式

​ 在Kotlin中由於語法的原因可以構造出一主多從的奇葩構造方式:

	class User(val name: String = "Bob") {
    init{
      ...
    }
    
    constructor(id: Long) : this(){
      ...
    }
    
    constructor(id: Long, email:String)this() {
      ...
    }
  }

能夠造出這種方式大多還是因爲根據參數的不同提供多種初始化方式,與上述的方法2實現的功能類似,然而因爲主構造方法不存在方法體,只能使用init,所以這種構造方式不如使用多個並列構造方法的方式直觀,徒增了閱讀難度,並不推薦使用這種方式。在主從構造方法混用的情況下,從構造方法必須通過":"調用主構造方法。主構造方法先於從構造方法執行。

但使用這種方式在需要多個構造方法,部分方法根據參數不同提供不同初始化方法,部分方法僅僅提供參數重載時,也能提供一定程度上的簡化,即通過主構造方法省略掉重載參數的構造方法。

4. init關鍵字

​ init關鍵字稱爲初始化語塊,主要是爲了彌補主構造方法沒有方法體的缺陷而存在的,我們將需要初始化的內容放在init語塊中。

​ 在Java中我們通常會將每個構造方法都會掉用到的共同代碼提取到一個方法中,在Kotlin中init語塊可以起到這個方法的作用,init並不依託於主構造方法存在,在使用多個從構造方法並列的形式中,依然可以通過init來執行通用代碼,而且init中的代碼會先於從構造方法執行。

5. constructor關鍵字

​ 我們通過constructor關鍵字來表示從構造方法。

​ 在主構造方法中我們需要constructor關鍵字與可見性修飾符一起使用來設置構造方法的可見性:

	class User private constructor(val name: String) {
		...
	}

6. Kotlin中的繼承

​ 在Kotlin中實質上是對類的繼承,而表現形式是對父類構造方法的繼承,我們需要選取使用合適的父類構造方法,例如,在主構造方法中進行繼承:

	class User(name: String) : Person(name) {
		...
	}

而在從構造方法的繼承形式上,我們依然需要選擇繼承父類方法:

class User : Person {
    constructor(name: String) : super(name) {

    }

    constructor(name: String, id: Long) : super(name, id) {

    }
}

當然,如果不使用super,可以選擇部分構造方法使用使用this調用自己已經繼承了父類構造方法的構造方法。

主從混用的形式以此類推,不再贅述。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章