美文网首页
每天学一点 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