Kotlin学习笔记基础篇五之构造函数

167 阅读4分钟

1、Kotlin field 关键字

//TODO Kotlin 定义类与field关键字学习

class KtBase {
    var name = "zhangsan"
    /*虚拟机做的事
          @NotNull
          private String name = "zhangsan"

          public void setName(@NotNull String name){
                this.name = name;
          }
          @NotNull
          public void getName(){
                return this.name;
          }


     */

    var value = "ABCDEFG"
        //写不写, 虚拟机都会生成下面的代码
        get() = field
        set(value) {
            field = value
        }

    var info = "adsdsad ok is success"
        get() = field.capitalize() //把首字母变大写
        set(value) {
            field = "**{$value}**"
        }
    /*
    背后做的事
        private String info = "adsdsad ok is success";

        public void setInfo(@NotNull String info){
            this.info = "**{$value}**"
        }

         @NotNull
          public void getInfo(){
                return StringKT.capitalize(this.info);
          }

     */

}

fun main() {
    KtBase().name = "lisi" //逻辑是 new KtBase() .setName ,所有虽然虚拟机里是private,这个地方也可以操作

    println(KtBase().name)//逻辑是new KtBase() .getName

    println("<<<<<<<<<<<<")

    println(KtBase().info)

    KtBase().info = "wangwu"

}

2、Kotlin竟态防范条件.also

//TODO Kotlin 计算属性 与防范静态条件


class KTBase {

    val number: Int = 0

    //计算属性,下面这样写覆盖了get()函数 ,覆盖了field本身
    val number2: Int
        get() = (1..1000).shuffled().first()//从1到1000取出随机值


    val info: String? = /*null*/ ""

    //    防范竟态条件,当你调用这个成员可能为null,就必须采用防范竟态条件
    fun getShowInfo(): String {

        //这种就是防范静态条件
        return info?.also {
            "最终info结果是:$this"
        } ?: "你原来是null,请检查代码"

    }
}


fun main() {

    println(KTBase().number)

//    KTBase().number = 9;//报错,是因为没有set函数,var有seT函数


    println(KTBase().number2)

}

3、Kotlin主构造函数

//TODO Kotlin 主构造函数


//主构造函数 规范说都是加_xxx的方式,临时输入类型,不能直接用,需要接收
//_name等等。都是临时类型,不能直接用,需要主构造函数
class KtBase(_name: String, _sex: Char, _age: Int, _info: String) {//主构造函数

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

    val sex = _sex

    val age = _age
        get() = field + 1

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

    fun show() {
        println(name)
        println(sex)
        println(age)
        println(info)
    }
}


fun main() {

    val p = KtBase(_name = "张三", _info = "学习KT语言", _age = 27, _sex = 'M')
    p.show()

}

4、Kotlin里主构造函数里定义属性

//TODO Kotlin 主构造函数


//一步到位,比较常用 var name:String 相当于var name = _name
class KtBase(var name: String, val sex: Char, val age: Int, var info: String) {//主构造函数


    fun show() {
        println(name)
        println(sex)
        println(age)
        println(info)
    }
}


fun main() {

    val p = KtBase(name = "张三", info = "学习KT语言", age = 27, sex = 'M').show()

}

5、Kotlin次构造函数

//TODO Kotlin 主构造函数与次构造函数


//一步到位,比较常用 var name:String 相当于var name = _name
class KtBase(name: String) {//主构造函数

    //次构造必须调用主构造,否则报错
    //为什么次构造必须调用主构造? 因为次构造很多,无法管理,必须由主构造统一管理
    constructor(name: String, sex: Char) : this(name) {
        println("两个参数的构造函数 name:$name,sex:$sex")
    }

    //三个参数的次构造函数
    constructor(name: String, sex: Char, age: Int) : this(name) {
        println("三个参数的构造函数 name:$name,sex:$sex,age:$age")
    }

    //四个参数的次构造函数
    constructor(name: String, sex: Char, age: Int, info: String) : this(name) {
        println("两个参数的构造函数 name:$name,sex:$sex,age:$age,info:$info")
    }
}


fun main() {

    val p = KtBase("李元霸")//调用主构造

    KtBase("张三", 'M')//调用两个参数次构造

    KtBase("张三", 'M', 27)//调用三个参数次构造

    KtBase("张三", 'M', 27, "学习KT语言")//调用四个参数次构造

}

注意:次构造函数必须实现主构造函数

6、Kotlin中的默认参数

//TODO Kotlin 构造函数中的参数


//一步到位,比较常用 var name:String 相当于var name = _name
class KtBase(name: String = "李元霸") {//主构造函数

    //次构造必须调用主构造,否则报错
    //为什么次构造必须调用主构造? 因为次构造很多,无法管理,必须由主构造统一管理
    constructor(name: String = "李连杰", sex: Char = 'M') : this(name) {
        println("两个参数的构造函数 name:$name,sex:$sex")
    }

    //三个参数的次构造函数
    constructor(name: String = "李小龙", sex: Char = 'M', age: Int = 27) : this(name) {
        println("三个参数的构造函数 name:$name,sex:$sex,age:$age")
    }

    //四个参数的次构造函数
    constructor(name: String = "李俊", sex: Char = 'W', age: Int = 26, info: String = "还在学习新的KT语言") : this(name) {
        println("两个参数的构造函数 name:$name,sex:$sex,age:$age,info:$info")
    }
}


fun main() {

    val p = KtBase("李元霸")//调用主构造

    KtBase("张三", 'M')//调用两个参数次构造

    KtBase("张三", 'M', 27)//调用三个参数次构造

    KtBase("张三", 'M', 27, "学习KT语言")//调用四个参数次构造


    KtBase() //优先调用主构造函数
}

7、Kotlin中的初始化 init{}

//TODO Kotlin 构造函数中的参数


//一步到位,比较常用 var name:String 相当于var name = _name
class KtBase(name: String = "李元霸") {//主构造函数

    //次构造必须调用主构造,否则报错
    //为什么次构造必须调用主构造? 因为次构造很多,无法管理,必须由主构造统一管理
    constructor(name: String = "李连杰", sex: Char = 'M') : this(name) {
        println("两个参数的构造函数 name:$name,sex:$sex")
    }

    //三个参数的次构造函数
    constructor(name: String = "李小龙", sex: Char = 'M', age: Int = 27) : this(name) {
        println("三个参数的构造函数 name:$name,sex:$sex,age:$age")
    }

    //四个参数的次构造函数
    constructor(name: String = "李俊", sex: Char = 'W', age: Int = 26, info: String = "还在学习新的KT语言") : this(name) {
        println("两个参数的构造函数 name:$name,sex:$sex,age:$age,info:$info")
    }
}


fun main() {

    val p = KtBase("李元霸")//调用主构造

    KtBase("张三", 'M')//调用两个参数次构造

    KtBase("张三", 'M', 27)//调用三个参数次构造

    KtBase("张三", 'M', 27, "学习KT语言")//调用四个参数次构造


    KtBase() //优先调用主构造函数
}

8、Kotlin 构造函数执行顺序

//TODO Kotlin 构造函数初始化顺序

//执行顺序

//第一步生成 val sex:Char
class KtBase(_name: String, val sex: Char) {//主构造函数

    //第二步  生成mName细节,由于写在init代码块前面,所以先生成,其实类成员和init是同时生成的
    val mName = _name

    init {
        val nameValue = _name//第三步 生成nameValue细节
        println("我是init代码块打印:nameValue:$nameValue")
    }


    constructor(name: String, sex: Char, age: Int) : this(name, sex) {
        //第五步:生成次构造的细节
        println("次构造函数三个参数被调用了,name:$name,sex:$sex,age:$age")
    }

    //第四步
    var test = "AAA"
}


fun main() {

    //先调用主构造,再调用init,再调用次构造
    KtBase("李元霸", '男', 27)
}

9、Kotlin构造函数延迟初始化

//TODO Kotlin 构造函数延迟初始化

//执行顺序

//第一步生成 val sex:Char
class KtBase() {//主构造函数

//   lateinit val AAA;// AAA无法后面修改,怎么延时初始化

    lateinit var result: String //等会再初始化,所以没有赋值

    //模拟服务器请求加载
    fun request() {//延迟初始化,属于懒加载
        result = "服务器加载成功,恭喜你"
    }

    fun showResponseResult() {
        if (::result.isInitialized) {
            println("resule:$result")
        } else {
            println("没有初始化加载")
        }

    }
}


fun main() {

    val p = KtBase()
    p.request()
    //使用之前加载,属于懒加载
    p.showResponseResult()
}

10、Kotlin 惰性初始化 byLazy

//TODO Kotlin 构造函数延迟初始化

//lateinit 是在使用时候,手动加载的懒加载方式,然后再使用

//惰性初始化 使用时候,自动加载的懒加载方式,然后再使用
class KtBase() {//主构造函数

    //普通方式,不使用惰性加载 (饿汉式,没有任何懒加载特点)

//    val databaseData1:String = readSQLServerDatabaseAction()

    val databaseData2 by lazy { readSQLServerDatabaseAction() }

    public fun readSQLServerDatabaseAction(): String {
        println("加载读取数据库开始")
        println("加载读取数据库数据中")
        println("加载读取数据库数据中")
        println("加载读取数据库数据中")
        println("加载读取数据库数据中")
        println("加载读取数据库数据中")
        println("加载读取数据库结束")
        return "数据库加载成功"

    }

}


fun main() {

    val p = KtBase()
    Thread.sleep(5000)
    println("即将开始使用")

    println("最终显示:${p.databaseData2}")
}

11、Kotlin 初始化陷阱

//TODO Kotlin 初始化学习 陷阱

class KtBase(_str: String) {
    //主构造函数
    //陷阱一:必须写在init前面,不然不能调用,使用顺序会走到int里
    var number = 9;
    val info: String

    val str = _str
    val content: String = getInfoMethod2()

    //    val str = _str//陷阱三,写在方法后赋值会崩溃,必须写前面
    init {
        info = "OK"
        getInfoMethod()
//        info = "OK"  //陷阱二:info写在方法后面会崩溃
        number = 81
    }

    fun getInfoMethod() {
        println("info:${info[0]}")
    }


    fun getInfoMethod2(): String = str

}


fun main() {

//   KtBase().getInfoMethod()

    println("内容的长度是:${KtBase("aaaaa").content.length}")
}