kotlin类的构造函数和属性

2022-11-06  本文已影响0人  Bfmall

一、 类的构造函数和属性

/**
 * DESC   : 类的构造函数和属性
 */
class KtBaseClassTest01 {

    companion object {
        const val TAG = "KtBaseClassTest01"
    }

    var name = "lanny"
        //get()和set()代码是隐式代码,不写也有,就是这个鸟样
        get() = field
        set(value) {
            field = value
        }
    /**
     * 背后做的事情
     * @NotNull
        private String name = "lanny";

        @NotNull
        public final String getName() {
        return this.name;
        }

        public final void setName(@NotNull String value) {
        Intrinsics.checkParameterIsNotNull(value, "value");
        this.name = value;
        }
     */

    var info = "hello lanny"
        get() = field.capitalize()//把首字母修改成大写

    // 不可变常量,没有set()方法,不能改变值
    val number1 : Int = 2
        get() = field
        /*set(value) {
            field = value
        }*/
    /**
     * number1背后的隐式代码:
     * public final int getNumber1() {
        return this.number1;
        }
     */

    //计算属性
    val number2 :Int
        get() = (1..100).shuffled().first()//从1到100取出随机值返回给getNumber2()函数
    /**
     * number2 背后的隐式代码,
     *
     * 转成java代码后,为什么没有看到number2属性定义?
     * 因为计算属性的功能,根本在getNumber2()里面,就没用用到number2属性,所以number2就失效了,以后用不到了
     *
     * public final int getNumber2() {
        byte var1 = 1;
        return ((Number)CollectionsKt.first(CollectionsKt.shuffled((Iterable)(new IntRange(var1, 100))))).intValue();
        }
     */

    var info2 :String? = ""

    //防范竞态条件,当你调用成员,这个成员可能为null,可能为空值"",就必须采用防范竞态条件,这是kt的规范
    fun getShowInfo2() :String {
        return info2?.let {
            Log.d(TAG, "getShowInfo2==>it=${it}")
            if (!it.isBlank()) {
                "info2=${it}"
            } else {
                "info2 为空"
            }
        } ?: "info2 为空"
    }


    fun testField01() {
        name = "Levone"

        info = "ni hao ma"

        //testField01==>name=Levone, info=Ni hao ma,getShowInfo2=info2 为空
        //可以看到背后的隐式代码,都调用了自己的get()方法,getName()和getInfo()
        //testField01==>name=Levone, info=Ni hao ma
        Log.d(TAG, "testField01==>name="+name+", info="+info
            +",getShowInfo2="+getShowInfo2())
    }
}

二、主构造函数中定义属性

2.1:
/**
 * DESC   :主构造函数中定义属性:
 * 规范来说,都是增加_XXX的方式,临时的参数类型,不能直接用,需要接收下来,成为变量才能用
 */
class KtBaseClassTest02(_name : String , _age : Int, _sex : Char, _info : String) {

    var name = _name
//       private get() = field
        get() = field//get()不允许私有化
        private set(value) {
            field = value
        }

    val age = _age
        get() = field + 1
        /*set(value) { //set只读的,不能修改的
            field = value
        }*/

    val sex = _sex
        get() = field

    val info = _info
        get() = "[${field}]"

    companion object {
        const val TAG = "KtBaseClassTest02"
    }

    fun showInfo() {
        // showInfo==>name=lanny, sex=M, age=27, info=[I'm a student]
        Log.d(TAG, "showInfo==>name="+name+", sex="+sex+", age="+age+", info="+info)
    }
}

2.2:

/**
 * DESC   : 在主构造函数中定义属性:
 * 加入参数的变量声明,就相当于var name = _name, val sex = _sex,。。。。
 * 只不过你看不到而已
 */
class KtBaseClassTest03(var name: String,  var age: Int, val sex: Char, val info :String) {

    companion object {
        const val TAG = "KtBaseClassTest03"
    }

    fun showInfo() {
        //showInfo==>name=lanny, age=26, sex=M, info=I'm a student
        Log.d(TAG, "showInfo==>name="+name+", age="+age +", sex="+sex+", info="+info)
    }
}

三、主构造函数和次构造函数

/**
 * DESC   : 主构造函数和次构造函数
 */
class KtBaseClassTest04(name : String) {

    companion object {
        const val  TAG = "KtBaseClassTest04"
    }

    //次构造函数必须调用主构造函数,否则不通过
    //为什么次构造函数必须调用主构造函数?为了更好的初始化设计
    /*constructor(name: String ,age : Int) {

    }*/


    //下面是正确写法----------

    // 2个参数的次构造函数,必须调用主构造函数
    constructor(name : String , age: Int) : this(name) {
        //2个参数次构造函数==>name=lanny, age=26
        Log.d(TAG, "2个参数次构造函数==>name=${name}, age=${age}")
    }

    // 3个参数的次构造函数,必须调用主构造函数
    constructor(name : String ,age : Int, sex : Char) : this(name) {
        //3个参数次构造函数==>name=lanny, age=26, sex=M
        Log.d(TAG, "3个参数次构造函数==>name=${name}, age=${age}, sex=${sex}")
    }

    // 4个参数的次构造函数,必须调用主构造函数
    constructor(name : String ,age : Int, sex : Char, info :String) : this(name) {
        //4个参数次构造函数==>name=lanny, age=26, sex=M, info=I'm a student
        Log.d(TAG, "4个参数次构造函数==>name=${name}, age=${age}, sex=${sex}, info=${info}")
    }
}

四、构造参数有默认值的情况

/**
 * DESC   : 构造参数有默认值的情况
 */
class KtBaseClassTest05(name : String) {
    companion object {
        const val  TAG = "KtBaseClassTest05"
    }

    // 2个参数的次构造函数,必须调用主构造函数
    constructor(name : String = "Andy", age: Int) : this(name) {
        //2个参数次构造函数==>name=lanny, age=26
        Log.d(TAG, "2个参数次构造函数==>name=${name}, age=${age}")
    }

    // 3个参数的次构造函数,必须调用主构造函数
    constructor(name : String ,age : Int, sex : Char = 'M') : this(name) {
        //3个参数次构造函数==>name=lanny, age=26, sex=M
        Log.d(TAG, "3个参数次构造函数==>name=${name}, age=${age}, sex=${sex}")
    }

    // 4个参数的次构造函数,必须调用主构造函数
    constructor(name : String ,age : Int = 26, sex : Char, info :String) : this(name) {
        //4个参数次构造函数==>name=lanny, age=26, sex=M, info=I'm a student
        Log.d(TAG, "4个参数次构造函数==>name=${name}, age=${age}, sex=${sex}, info=${info}")
    }
}
上一篇下一篇

猜你喜欢

热点阅读