美文网首页
每天学一点 Kotlin -- 类的属性

每天学一点 Kotlin -- 类的属性

作者: 冯可乐同学 | 来源:发表于2021-11-13 19:58 被阅读0次

    ----《第一季Kotlin崛起:次世代Android开发 》学习笔记

    总目录:每天学一点 Kotlin ---- 目录
    上一篇:每天学一点 Kotlin -- 类的构造函数
    下一篇:每天学一点 Kotlin -- 类的进阶:继承

    1. 属性

    1.1 在类定义中的属性可以有很多类型,比如 Int,Double,Boolean,String,还可以是其他自己定义的类。

    1.2 函数也可以作为类的属性,举个栗子:

    class NumberCompution(val num1: Int, val num2: Int, var operator: (Int, Int) -> Int){
    
        fun operation(){
            println("Operation Result: ${operator(num1, num2)}")
        }
    }
    fun main(args: Array<String>) {
    
        val numComp = NumberCompution(10, 20, {x, y -> x + y})
        numComp.operation()
        numComp.operator = {x, y -> x * y}  // 给属性变量重新赋值
        numComp.operation()
    }
    

    打印结果:

    Operation Result: 30
    Operation Result: 200
    

    在主体中有返回值,但是省略 return,我们可以直接写要返回的结果。

    1.3 在类中定义函数属性不需要特别谨慎,因为 Kotlin 仍然建立在 JVM 虚拟机上,而目前的 JVM 处理垃圾的方式基本上是根搜索法,即使是互相引用,也能被正常释放。

    2. 属性的赋值和取值(setter 和 getter)

    2.1 setter 和 getter:对属性是否可修改和是否可外部访问的描述。

    2.2 比如在下面的这个类中:

    class CustomType{
        var nameA = "nameA"
        val nameB = "nameB"
    }
    

    (1) getter: nameA 和 nameB 在类外部都可以通过 . 号获取的各自的值,所以都有 getter;
    (2) setter: nameA 在类内部或外部都是可以修改的,而 nameB 在初始化后是不能修改的。所以 nameA 具有 setter,而 nameB 不具有 setter。

    2.3 对于只读属性:
    (1) 只读属性用 val 代替 var
    (2) 只读属性不允许 setter

    2.4 setter 和 getter 的使用:

    fun main(args: Array<String>) {
        testPerson2()
    }
    
    fun testPerson2() {
        var person2 = Person2(16)
        println("isAudlt: " + person2.isAudlt)
    
        person2.addAge = 20
        println("isAudlt: " + person2.isAudlt)
    }
    
    class Person2(age: Int){
        var age = age
        val isAudlt: Boolean
            get() = age >= 18
    
        var addAge: Int
            get() = 0
            set(value){
                age += value
            }
    }
    

    打印结果:

    isAudlt: false
    isAudlt: true
    

    2.5 如果需要一个属性在类的内部能够修改它,但是在外部不能修改它,我们可以把 setter 隐藏起来,也就是使用 private 来修饰 setter。举个栗子:

    fun main() {
        testPerson3()
    }
    
    fun testPerson3() {
        var person3 = Person3(26)
        println(person3.isAudlt)
        person3.age = 20
        println(person3.isAudlt)
        person3.addAge = 10
        println(person3.isAudlt)
    //    person3.isAudlt = false  // 编辑器直接报红线了
    }
    
    class Person3(age: Int){
        var age: Int = age
        var isAudlt: Boolean = false
            private set
        
        var addAge: Int = 0
            set(value){
                age += value
                if(age >= 18){
                    isAudlt = true
                }
            }
    }
    

    打印结果:

    isAudlt: false
    isAudlt: true
    isAudlt: true
    

    属性 isAudlt 虽然定义的是 var,但是用了 private set,所以只有在类的内部能够修改,在外部不能给它设置值,因为 set 在外部是不可见的。在 addAge 这个属性的 setter 处加了一个判断,如果自增后的年龄大于等于18,那么 isAdult 就设置为 true 了。但是有一点一定要注意:当我们在构造的时候传入 age 或者在构造完成后手动修改 age,即使 age 大于等于18也不会改变 isAdult 的值,因为在构造的时候不会触发任何 setter,而在构造完成后修改属性时没有相应的 setter 对 isAdult 进行修改。

    2.6 注意:在构造时是不会触发和调用任何 setter 的。

    3. 幕后字段

    3.1 在 setter 中赋值:在 setter 中如何对当前属性赋值呢?在 setter 中赋值,这个属性改变后不是再一次触发 setter 了么,这不就是无限循环了么?要解决这个问题,Kotlin 提供了一个很好的机制,那就是幕后字段。

    3.2 举个栗子:

    fun main() {
        testPerson4()
    }
    
    fun testPerson4() {
        println("testPerson4 start... ")
        var person4 = Person4(25)
        println(person4.isAudlt)
        person4.age = 20
        println(person4.isAudlt)
        person4.addAge = 10
        println(person4.isAudlt)
    }
    
    class Person4(age: Int) {
        var isAudlt = false
            private set
    
        var age: Int = age
            set(value) {
                field = value
                if (age >= 18) {
                    isAudlt = true
                }
            }
    
        var addAge: Int = 0
            set(value) {
                age += value
            }
    }
    

    打印结果:

    testPerson4 start... 
    false
    true
    true
    
    相关代码:https://gitee.com/fzq.com/test-demo

    相关文章

      网友评论

          本文标题:每天学一点 Kotlin -- 类的属性

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