1. 程式人生 > >Kotlin系列之主構造方法和初始化語句塊

Kotlin系列之主構造方法和初始化語句塊

前面我們已經說過類和介面的知識點,今天來看看Kotlin中的主構造方法和初始化語句塊。

我們知道在Java中也存在構造方法的概念,也有初始化塊的概念。所以今天還是拿Kotlin和Java進行對比學習。

Java中的構造方法和初始化塊

在Java中構造方法有以下幾點的規則。
1 . 構造方法沒有返回值,方法名必須與類名相同

2 . 如果沒有顯式宣告構造方法,Java會給我們生成一個預設的不帶任何引數的構造方法

在Java中的初始化塊又分為普通初始化塊靜態初始化塊,他們的規則如下。
1 . 普通初始化塊在每次物件建立時被呼叫,靜態初始化塊只在類被載入時呼叫,且只會被呼叫一次

2 . 普通初始化塊用來在一個物件建立時初始化其中的一些引數

下面通過程式碼來簡單解釋以下上面的規則。

Java程式碼

package ja;

public class Main {
    //靜態初始化程式碼塊
    static {
        System.out.println("類被載入了...");
    }

    private int value;
    private int num;

    //普通初始化程式碼塊
    {
        num = 10;
    }

    //構造方法用來初始化引數
    public Main(int value
){ this.value = value; } public int add(int other){ return this.value + this.num + other; } }

上面都是java的基礎知識,寫出來主要是方便與Kotlin的進行對比。

Kotlin中的主構造方法和初始化語句塊

在Kotlin中也存在和Java中相似的概念,但也又一些差異。
這裡有一個概念是主構造方法。在Kotlin中一個類同樣可以宣告多個構造方法,但Kotlin將他們分為主構造方法從構造方法
主構造方法是一個主要且簡潔的初始化類的方法,而且它宣告在類的外部,而從構造方法

是宣告在類的內部。今天我們先說說主構造方法和與之相關的初始化語句塊

在Kotlin中構造方法的宣告需要使用到constructor關鍵字,初始化語句塊的宣告需要使用到關鍵字init。在Kotlin中構造方法一般是用於傳入一些建立類時需要的引數,配合初始化語句塊來對類的屬性進行初始化。下面用程式碼來實際說一下。

Kotlin程式碼

//該類的主構造方法需要傳入name引數
class User constructor(name: String){
    //類的name屬性
    val name: String

    //初始化語句塊用於配合構造方法給屬性賦初始值
    init {
        this.name = name
    }
}

上面的程式碼還是很好理解的,其實就相當於把我們的構造方法和類的宣告放在了一起。注意上面的this和我們java中的用法是一樣的,都是在於構造方法的引數名和類的屬性名相同時來區分兩者。

當然Kotlin是一門追求簡潔的語言,我們可以把上面的程式碼進一步簡化。像下面這樣。

Kotlin程式碼

class User (name: String){
    //類的name屬性
    val name = name
}

直接省略了constructor關鍵字和初始化語句塊,直接賦值即可。

當你覺得這樣已經夠簡潔的時候,還有更簡潔的,想下面這樣。

Kotlin程式碼

class User (val name: String)

直接將val關鍵字載入構造方法屬性前面,就完成了構造方法引數的宣告和類屬性的宣告和賦值,甚至連{}也不需要了。

Kotlin中的構造方法新特性

除了上面簡潔的語法,還有很多新特性。我們在前面的文章中說過,一個方法的引數可以又預設值,也可以在傳入方法引數時帶上引數名使程式碼可讀性更好。由於構造方法也是方法,我們同樣可以使用這些特性,就像下面程式碼描述的那樣。

Kotlin程式碼

//構造方法引數帶預設值
class User (val name: String, val isMan: Boolean = false)

那我們如何使用上面的類呢?

Kotlin程式碼

fun main(args: Array<String>){
    //第二個引數使用了預設值
    val user1 =  User(name = "Mike")

    val user2 = User(name = "Tom", isMan = true)
}

是不是程式碼簡潔清楚了很多呢。

Kotlin構造方法與繼承

我們知道在Java中如果我們沒有顯式宣告一個構造方法,就會為我們預設新增一個無參的構造方法,在Kotlin中也是一樣的。
那麼當我們涉及到繼承時,我們該怎麼寫呢?在Kotlin中當你繼承一個類不再只是寫出類名就可以了,而是要給你繼承類的構造方法同時傳入引數j將,就像下面這樣。

Kotlin程式碼

open class User (val name: String, val isMan: Boolean = false)

class GoogleUser(name: String, val age: Int): User(name){

}

上面的程式碼中,我們建立GoogleUser這個子類,並且將它的構造方法的name引數傳遞給了父類的構造方法。同時我們還為子類增加了一個新的屬性age
當然,如果我們繼承的父類沒有指定構造方法,由於有預設構造方法的存在,我們在繼承時必須要注意。像下面的程式碼一樣。

Kotlin程式碼

open class Father

class Son: Father(){
    //...
}

這裡我們在繼承father類時必須有(),因為這裡的意義是構造方法。

我們前面也說過介面是沒有構造方法,不能被例項化的,所以就沒有(),像下面這樣。

Kotlin程式碼

interface Clickable

class View: Clickable{

}

寫在最後

可以看出Kotlin在模仿Java的一些方面的同時,可以保證我們用更簡潔清楚和更少的程式碼來完成我們的工作。