Kotlin彙總2-類構造,屬性,字段

1.類構造函數

1.1 基礎構造函數

class Person constructor(firstName: String) {
}

首選要清楚kotlin的默認修飾是public,所以上面的也可以簡寫成下面的

class Person(firstName: String) {
}

如果像把構造函數變成private

class Person private constructor(firstName: String) {
}

多個參數的構造函數

class Person private constructor(firstName: String, var b: String) {
}

給構造函數的參數指定默認值

class Person private constructor(firstName: String, var b: String = "bbbb") {
}

//調用如下
var p = Person("dave")
var p = Person("dave", "b")

1.2 第二級構造函數

只有第二級構造函數

class Child(){
    constructor(c: Child, a: String = "aaa") {

    }
}

當第二級構造函數和基礎構造函數同時存在時,第二級構造函數必須代理基礎構造函數

class Child(val a: String){
    constructor(c: Child, a: String = "aaa") : this(a){//使用this代理了基礎構造函數

    }
}

另外需要注意,下面寫法是錯誤的

class Child(){
    constructor(val c: Child, var a: String = "aaa") {
        //第二級構造函數的參數不能使用val或者var修飾
    }
}

2.屬性

2.1 屬性定義的完整語法

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

屬性必須被賦值或者使用get/set,比如幾種情況

var a = "aaa"
var b = "bbb"
var c: String //因爲var是可讀可寫屬性,所以必須set/get都有
    set ...
    get ...
val d: String //因爲val是隻讀屬性,所以只需要get
    get ...
var f = "ffff"
    private set //因爲f屬性的set方法默認是public,顯性聲明private set之後,f屬性的set方法就變成private了

2.2 延緩屬性的初始化

因爲屬性必須初始化,但是有些時候有需要在特定情況下延遲它的初始化,可以使用lateinit關鍵字

public class MyTest {
    lateinit var subject: TestSubject

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

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

2.3 覆寫屬性

open class Foo {
    open val x: Int get { ... }
}

class Bar1 : Foo() {
    override val x: Int = ...//子類覆寫了父類的屬性x
}

需要注意可以用var覆寫val,但是不能val覆寫var

2.4 屬性代理

通過by關鍵字

class Example {
    var p: String by Delegate() //by關鍵字代理屬性
}

class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "$thisRef, thank you for delegating '${property.name}' to me!"
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$value has been assigned to '${property.name} in $thisRef.'")
    }
}

3. 反向字段和反向屬性

3.1 反向字段

kotlin的類不支持字段,但是當使用自定義存儲時又需要反向字段,這個時候可以用field關鍵字

var counter = 0 // the initializer value is written directly to the backing field
    set(value) {
        if (value >= 0) field = value
    }

3.2 反向屬性

有些場景不適合使用反向字段,可以使用反向屬相

private var _table: Map<String, Int>? = null
public val table: Map<String, Int>
    get() {
        if (_table == null) {
            _table = HashMap() // Type parameters are inferred
        }
        return _table ?: throw AssertionError("Set to null by another thread")
    }

上面這樣寫,只有table被調用到了,_table纔會被創建。

4. 編譯時常量

使用const關鍵字修飾,適用於如下場景
- 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() { ... }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章