屬性與字段

回到目錄
項目源碼 kotlin-class 項目


屬性必須初始化, 如果沒有直接賦值, 就必須寫進構(gòu)造函數(shù)中

聲明在主構(gòu)造函數(shù)中的屬性:

class PfA(val a: Int, var b: Int)

聲明屬性, 然后在次構(gòu)造函數(shù)中初始化或 init 塊中初始化.

class PfB {
    var a: Int
    val b: Int
    val c: Int?
    // 次構(gòu)造函數(shù)中不能有 val, var
    constructor(a: Int, b: Int, c: Int) {
        this.a = a
        this.b = b
        this.c = c
    }
}

class PfBB(a: Int, b: Int) {
    val a = a
    val b: Int
    init {
        this.b = b
    }
}

直接賦值初始化的屬性:

class PfC {
    var a = 0
    val b = 1
    // val 類型屬性可以這樣初始化, 但是 var 不行!
    // 這樣是沒有 backing field 的
    val c get() = true
}

完整的屬性聲明語法:

var <propertyName>[: <PropertyType>] [= <property_initializer]
    [<getter>]
    [<setter>]

初始化表達式, getter, setter 是可選的.

如果屬性類型可以被初始化表達式推斷, 或從 getter 的 return 返回值推斷.

    // val 只有 getter, 不能有 setter
    // 可以從 getter 返回值推斷類型, 所以類型可以不寫
    val allByDefault
        get() = 1 // val 可以用 getter, 可以省略初始化表達式和類型

Backing Fields

Kotlin 中默認實現(xiàn)了 java 中的 getter, setter. 但也可以自定義, 修改邏輯.

注意: 如果不在構(gòu)造函數(shù)中初始化, var 變量必須使用初始化表達式, 而 val 變量可以用
getter 代替初始化表達式

    // Backing Fields
    // 使用 field 標識符, 在 getter setter 內(nèi)可以使用, 用來設(shè)置屬性值.
    var getsetvar: Int = 1
        set(value) {
            field = value + 1
        }

    // 使用 getter 可以用來做一些邏輯判斷
    var getsetvar2: Int = 1 // 這里是初始化
        get() {
            if(field == 1) {
                println("值是 1, 返回 0")
                return 0
            }
            return field
        }
        set(value) {
            field = value + 1
        }

測試驗證上面的屬性:

    @Test fun testProperties() {
        // 初始值是 1
        assertEquals(1, address.getsetvar)
        // 設(shè)置為 2
        address.getsetvar = 2
        // setter 會加 1, 所以值應(yīng)該是 3
        assertEquals(3, address.getsetvar)
    }

    @Test fun testProperties2() {
        // 初始值是 1, getter 判斷如果等于 1 就返回 0
        assertEquals(0, address.getsetvar2)
        // 設(shè)置為 3, setter 會加 1, 所以是 4
        address.getsetvar2 = 3
        assertEquals(4, address.getsetvar2)
    }

訪問器 getter setter 的可見性

var setterVisibility: String = "abc"
    private set // the setter is private and has the default implementation

var setterWithAnnotation: Any? = null
    @Inject set // annotate the setter with Inject

Compile-Time Constants

編譯時常量:
- Top-level or member of an object
- Initialized with a value of type String or a primitive type
- No custom getter

這類屬性可以用在注解中:

const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"

@Deprecated(SUBSYSTEM_DEPRECATED) fun foo() { ... }

延遲初始化屬性(Late-Initialized Property)

用于依賴注入或測試方法中在 @setup, @before 等方法中再進行初始化.

public class MyTest {
    lateinit var subject: TestSubject

    @SetUp fun setup() {
        subject = TestSubject()
    }

    @Test fun test() {
        subject.method()  // dereference directly
    }
}

回到目錄

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容