美文网首页
属性与字段

属性与字段

作者: codergege | 来源:发表于2018-11-23 22:00 被阅读0次

    回到目录
    项目源码 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
        }
    }
    

    回到目录

    相关文章

      网友评论

          本文标题:属性与字段

          本文链接:https://www.haomeiwen.com/subject/slbsqqtx.html