属性与字段

2018-11-23  本文已影响0人  codergege

回到目录
项目源码 kotlin-class 项目


属性必须初始化, 如果没有直接赋值, 就必须写进构造函数中

声明在主构造函数中的属性:

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

声明属性, 然后在次构造函数中初始化或 init 块中初始化.

class PfB {
    var a: Int
    val b: Int
    val c: Int?
    // 次构造函数中不能有 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 中默认实现了 java 中的 getter, setter. 但也可以自定义, 修改逻辑.

注意: 如果不在构造函数中初始化, var 变量必须使用初始化表达式, 而 val 变量可以用
getter 代替初始化表达式

    // Backing Fields
    // 使用 field 标识符, 在 getter setter 内可以使用, 用来设置属性值.
    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)
        // 设置为 2
        address.getsetvar = 2
        // setter 会加 1, 所以值应该是 3
        assertEquals(3, address.getsetvar)
    }

    @Test fun testProperties2() {
        // 初始值是 1, getter 判断如果等于 1 就返回 0
        assertEquals(0, address.getsetvar2)
        // 设置为 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
    }
}

回到目录

上一篇 下一篇

猜你喜欢

热点阅读