Kotlin语言学习笔记

目录


汇总一

1.变量

const val PI=3.14  //定义编译时常量,只能在函数之外定义
fun main(){
    println("hello world")
    // TODO 声明变量
    /*
      可读可改  变量名    类型    值
    * var     name  :  String="mumu";
    * */
    //TODO 内置数据类型
    /*
        String          字符串
        Char            单字符
        Boolean         true/false
        Int             整型
        Double          小数
        List            集合
        Set             无重复的元素集合
        Map             键值对集合
    */

    //TODO  只读变量
    val name : String ="mumu" //不可修改的
}

2.kotlin的range表达式

    val number = 101
    if(number in 90..100){
        println("优秀")
    }else if(number in 0..60){
        println("不及格")
    }else if(number !in 0..100){
        println("分数不在0到100范围内")
    }

3.kotlin的when表达式

 	val week=2
    //java的if表达式
    //kotlin的if表达式,有返回值的
    val info = when(week){
        1 -> "今天是星期一"
        2 -> "今天是星期二"
        else->{
            println("忽略星期几")
        }
    }
    println(info)

4.kt的String模板

 val garden="龙山公园"
    val time = 5
    println("今天去了${garden}玩,玩了${time}个小时")
    //因为kt的if时表达式,所以可以更灵活;java的if是语句,有局限性
    val isLogin=true
    println("server response result: ${if(isLogin) "恭喜,登录成功" else "登陆失败"}")

5.kt的函数

fun main(){
    //TODO kt的函数头学习
    method01(18,"张三")

    //TODO kt函数参数的默认参数
    action01("木木",19)
    action02("李四")
    action03("小小",20)

    //TODO kt语言的反引号中函数特点
    `登录功能测试20221209,测试人MuMa`("MuMa","123456")
    //is 在kt里面是关键字,所以在这里需要用到反引号
    test.`is`()
}
private fun action01(name:String,age:Int){
    println("我的姓名是$name,年龄是$age")
}
private fun action02(name:String,age:Int=19){
    println("我的姓名是$name,年龄是$age")
}
private fun action03(name:String="张三",age:Int=18){
    println("我的姓名是$name,年龄是$age")
}

//TODO kt语言的反引号中函数特点
private fun `登录功能测试20221209,测试人MuMa`(username:String,userpwd:String){
    println("用户名:$username,密码:$userpwd")
}

6.kt的匿名函数

fun main(){
    //TODO kt的匿名函数
    val len="muma".count()
    println(len) //输出长度

    val len2 ="muma".count{
        it == 'm'
    }
    println(len2)

    //TODO kt的函数类型&隐式返回学习
    //现在写函数
    //第一步:函数输入输出声明
    val methodAction : () -> String
    //第二步:对上面函数的实现
    methodAction={
        val score=99999
        "${score}MuMa"
        //匿名函数不要写return,最后一行是返回值
    }
    //第三步:调用次函数
    println(methodAction())

    //TODO kt的函数参数学习
    //第一步:函数输入输出声明,对声明函数的实现
    val methodAction1:(Int,Int,Int)->String ={num1,num2,num3 ->
        val input = 8899
        "$input muma 参数一:$num1,参数二:$num2,参数三:$num3"
        //第三步调用此函数
    }
    println(methodAction1(11, 22, 33))

    //TODO kt语言的it关键字特点
    val methodAction2 : (Int,Int,Int) -> String = {num1,num2,num3 ->
        val input = 89
        println("$input num1:$num1,num2:$num2,num3:$num3")
        "$input num1:$num1,num2:$num2,num3:$num3"
    }
    methodAction2(11,22,33)
    val methodAction3 : (Double) -> String = {
        "$it mumu"
    }
    println(methodAction3(3.1415))

    //TODO kt语言的匿名函数类型推断
    //方法名:必须指定参数类型和返回类型
    //方法名=类型推断返回类型
    val method1 = {s1:Double,s2:Float,s3:Int ->
        "s1:$s1,s2:$s2,s3:$s3"
    }
    println(method1(5.6, 3.1f, 66))
    val method2={num:Int->
        num
    }
    println(method2(36))

    //TODO kt语言的lambda学习
    //匿名函数==lambda表达式
    val addResultMethod ={num1:Int,num2:Int->
        "两个数相加的结果是:${num1+num2}"
    }
    println(addResultMethod(2, 2))

    //匿名函数入参Int        返回Any类型
    //lambda表达式Int       lambda表达式的结果Any类型
    val weekResultMethod = {number:Int->
        when(number){
            1->"星期一"
            2->"星期二"
            3->"星期三"
            else->-1
        }
    }//weekResultMethod 函数: (Int)->Any
    println(weekResultMethod(3))
    //总结 匿名函数 属于 lambda

    //TODO 在函数中定义参数是函数的函数
    loginAPI("mumu","1234"){msg:String,code:Int->
        println("提示:msg:$msg,code:$code")

    }

}
    //TODO 在函数中定义参数是函数的函数
const val USER_NAME_SAVE_DB="mumu"
const val USER_PWD_SAVE_DB="123456"
//todo 如果函数有lambda,尽量使用inline关键帧(内联函数),这样内部会做优化,减少函数开辟和对象开辟的损耗
public inline fun loginAPI(username: String, userpwd: String,responseResult : (String,Int) -> Unit) {
    if(username == null || userpwd == null){
        TODO("用户名或密码为null")
    }
    //校验
    if(username.length>3 && userpwd.length>3){
        if(wbeServiceLoginAPI(username,userpwd)){
            return responseResult("login success",200)
        }else{
            return responseResult("login error",444)
        }
    }else{
        TODO("用户名或密码格式不正确")
    }
}
fun wbeServiceLoginAPI(name:String,pwd:String) : Boolean{
    return name==USER_NAME_SAVE_DB && pwd==USER_PWD_SAVE_DB
}

7.kt语言的函数引用学习

fun main(){
    login("mumu","12345"){msg:String,code:Int->
        println("提示最终登陆结果:msg:$msg,code:$code")
    }
    login("mumu","123456",::methodResponseResult)//函数的引用
}
fun methodResponseResult(msg:String,code:Int){
    println("提示最终登陆结果:msg:$msg,code:$code")
}
const val USER_NAME_SAVE_DB1="mumu"
const val USER_PWD_SAVE_DB1="123456"
inline fun login(name:String,pwd:String,responseResult:(String,Int)->Unit){
    if(name==USER_NAME_SAVE_DB1 && pwd==USER_PWD_SAVE_DB1){
        responseResult("登录成功",200)
    }else{
        responseResult("登录失败",444)
    }

}

8.kt语言的函数类型作为返回类型

fun main(){
//    show("学习kt语言")
    val showMethod=show("show")
    //showMethod 是 show函数的返回值,只不过这个返回值是一个函数,所以可以调用showMethod这个函数
    println(showMethod("张三",12))
}
//show函数 再返回一个匿名函数
fun show(info:String) : (String,Int) -> String{
    println("我是show函数 info:$info")
    return { name:String,age:Int->
        "匿名函数:name:$name,age:$age"
    }
}

9.kt语言的匿名函数和具名函数

fun main(){
    //匿名函数
    showPersonInfo("张三",18,'男',"kotlin"){
        println("显示结果:$it")
    }
    //t1具名函数
    showPersonInfo("李四",28,'女',"java",::showResultImpl)

    //TODO kt语言的可空性特点
    //第一种:默认是不可空类型,不能随便给null
    var name1:String = "张三" //不能是非空类型
    //第二种:声明时指定为可空类型
    var name2:String ?
    name2=null
    println(name2)


}
//t1
fun showResultImpl(result: String){
    println("显示结果:$result")
}
inline fun showPersonInfo(name:String,age:Int,sex:Char,study:String,showResult:(String)->Unit){
    val str="name:$name,age:$age,sex:$sex,study:$study"
    showResult(str)
}

10.kt语言的安全调用操作符

fun main(){
    //TODO kt语言的安全调用操作符
    var name : String? ="abc"
    //name=null
    //name. //name是可空类型,可能是null,想要用name,必须给出补救措施
    val r=name?.capitalize() //name是可空类型,如果真的是null,?后面这一段代码不执行,就不会引发空指针异常
    //todo kt语言中非空断言操作符特点
    var s=name!!.capitalize() //!! 断言 不管name是不是null都执行
    //规矩:如果百分百能保证name不是空值,才能使用!!断言,否则空指针异常风险
    println(r)

    //TODO kt语言使用带let的安全调用
    var name1 : String? =null
    //name1="zhangsan"
    //name是可空类型,如果真的是null,?后面这一段代码不执行,就不会引发空指针异常
    var r1=name1?.let{
        //let可以把name1拿到内部用
        //it==name1本身
        //执行到这里 it 一定不为null
        if(it.isBlank()){
            "Default"
        }else{
            it
        }
    }
    println(r1)

    //TODO kt语言的空合并操作符
    println(name1?.let{ "【$it】" } ?: "原来你是null")
}

汇总二

1.kt语言的substring

const val INFO="Muma like kotlin"
fun main(){
    val indexOf=INFO.indexOf("k")
    println(INFO.substring(0 , indexOf))
    println(INFO.substring(0 until indexOf)) //kt语言基本上用此方式 0 until indexOf
}

2.kt语言的split操作

 	val jsonText="mumu,zhangsan,lisi,zhaowu"
    val list=jsonText.split(",") //list 自动类型推断成 list==List<String>
    //直接输出list集合 不解构
    println("分割后的list里面的元素有:$list")
    //c++ 解构,kt也有解构
    val (m1,m2,m3,m4) = list
    println("解构四个只读变量的值是:m1:$m1,m2:$m2,m3:$m3,m4:$m4")

3.kt语言的replace完成加密解码操作

 	val sourcePwd="ABCDE"
    println("原始密码是:$sourcePwd")
    //加密操作:把字符替换成数字
    val newPwd = sourcePwd.replace(Regex("[ABCDE]")){
        when(it.value){
            "A" -> "3"
            "B" -> "5"
            "C" -> "6"
            "D" -> "2"
            "E" -> "1"
            else -> it.value
        }
    }
    println("加密后的密码是:$newPwd")

4.kotlin语言中== & ===比较操作

 	val name1="Muma"
    val name2="muma".capitalize()
    println(name1 == name2) //true
    println(name1 === name2) //false

5.字符串遍历

 	val str = "ABCDEFG"
    str.forEach { /*c-> //覆盖掉默认的it参数名,改$it为$c*/
        print("字符:$it,")
    }

6.数字类型安全转换函数

    val num : Int = "666".toInt()
    println(num)
    //字符串放入了double类型,无法转换成Int,会崩溃
    //例如:val num : Int = "3.14".toInt()
    //解决崩溃问题
    val num2 : Int? = "3.14".toIntOrNull()
    println(num2 ?: "原来你是null") //空合并

7.Double转Int与类型格式化

 	println(34.65.toInt()) //不会四舍五入
    println(34.65.roundToInt()) //四舍五入
    println("%.3f".format(35.6578)) //保留三位小数,输出的是String类型

汇总三(内置函数)

1.apply内置函数

val info = "Mumu Like Kotlin"
    //普通方式
    println("info字符串长度是:${info.length}")
    println("info最后一个字符是:${info.length -1}")
    println("info全部转成小写是:${info.toLowerCase()}")

    //apply内置函数方式
    //特点:始终返回info本身String类型
    val infoNew =info.apply {
        //一般情况下,匿名函数都会持有一个it,apply会持有有个this==info本身
        println("apply匿名函数里面打印的:$this")
        println("info字符串长度是:$length")
        println("info最后一个字符是:${this[length -1]}")
        println("info全部转成小写是:${toLowerCase()}")
    }
    //apply使用规则
    //apply始终返回 info本身,所以可以链式调用
    info.apply {
        println("info字符串长度是:$length")
    }.apply {
        println("info最后一个字符是:${this[length -1]}")
    }.apply {
        println("info全部转成小写是:${toLowerCase()}")
    }

    //普通写法
    val file=File("C:\\Users\\Administrator\\Desktop\\a.txt")
    file.setExecutable(true)
    file.setReadable(true)
    println(file.readLines())

    //apply写法
    file.apply {
        setExecutable(true)
    }.apply {
        setReadable(true)
    }.apply {
        println(readLines())
    }

2.let内置函数

fun main(){
    //todo let内置函数
    //普通方式,对集合中第一个元素进行相加
    //let方式,对集合中第一个元素进行相加
    //普通方式,对值判null,并返回
    //let方式,对值判null,并返回

    //普通方式,对集合中第一个元素进行相加
    val list= listOf(3,5,2,6,7)
    val value1=list.first()+list.first()
    println(value1)

    //let方式,对集合中第一个元素进行相加
    //let函数的返回类型,根据匿名函数的最后一行变化而变化
    val value2=listOf(3,5,2,6,7).let {
        it.first()+it.first() //let的特点,匿名函数最后一行作为返回值;但apply永远返回元素本身
    }
    println(value2)
    println(getMethod3("Mumu"))
}
//普通方式,对值判null,并返回
fun getMethod(value:String?):String{
    return if (value==null) "传入的值是null" else "欢迎回来${value}"
}
//普通方式,对值判null,并返回,简化版本
fun getMethod2(value:String?) = if (value==null) "传入的值是null" else "欢迎回来${value}"

//let方式,对值判null,并返回
fun getMethod3(value: String?) : String{
    return value?.let{
        "欢迎回来$it"
    } ?: "传入的值是null"
}
//let方式,对值判null,并返回,简化版本
fun getMethod4(value: String?) =
    value?.let{
        "欢迎回来$it"
    } ?: "传入的值是null"

3.run内置函数

fun main(){
    //todo run内置函数
    val str = "MuMa like Kotlin"
    //run函数返回类型根据最后一行变化而变化,和let一样
    //run函数的匿名函数里面持有的this==str本身,和apply一样
    //具名函数配合run函数
    str
        .run(::isLong)
        .run(::showText)
        .run(::mapText)
        .run(::println)
    //匿名函数调用给run执行
    str
        .run{
            str.length>5
        }
        .run {
            if (this) "你的字符合格" else "你的字符不合格"
        }
        .run {
            "【$this】"
        }
        .run(::println)
}
fun isLong(str : String) = str.length>5
fun showText(islong : Boolean) = if (islong) "你的字符合格" else "你的字符不合格"
fun mapText(getText : String) = "【$getText】"

4.with内置函数

fun main(){
    //具名操作
    val str="张三"
    val s1 = with(str,::getStrLen)
    val s2 = with(s1,::getLenInfo)
    val s3 = with(s2,::getInfoMap)
    with(s3,::shows)

    //匿名函数
    with(with(with(with(str){
        this.length
    }){
        "你的字符串长度是:$this"
    }){
        "【$this】"
    }){
        println(this)
    }
}
fun getStrLen(str : String) = str.length
fun getLenInfo(len : Int) = "你的字符串长度是:$len"
fun getInfoMap(info : String) = "【$info】"
fun shows(content : String) = println(content)

5.takeIf内置函数

fun main(){
    //todo takeIf内置函数
    val result = checkpermissionAction("root","root")
    if(result != null){
        println("欢迎${result}尊贵用户登录系统,拥有超级权限")
    }else{
        println("没有权限")
    }

    println(checkpermissionAction2("root","root"))
    //小结:一般情况下,都是takeIf + 空合并一起使用
}

//前端
fun checkpermissionAction(name : String , pwd : String) : String?{
    return name.takeIf { permissionSystem(name,pwd) }
}
//takeIf + 空合并操作符
fun checkpermissionAction2(name : String , pwd : String) : String{
    return name.takeIf { permissionSystem(name,pwd) } ?: "没有权限"
}
//权限系统
private fun permissionSystem(username:String,userpwd:String) : Boolean{
    return if(username == "root" && userpwd == "root") true else false
}


汇总四

1.list

//todo list创建和元素获取
    val list= listOf<String>("Mumu","zhangsan","lisi","wangwu")
    //普通取值方法
    println(list[0])
    //防止崩溃取值方法:getOrElse,getOrNull
    println(list.getOrElse(4){"越界"})
    println(list.getOrNull(4)) //null
    //getOrNull + 空合并操作符
    println(list.getOrNull(4) ?: "越界")

    //todo 可变List集合
    val list1 = mutableListOf("Mumu","zhangsan","lisi","wangwu")
    list1.add("zhaoliu")
    list1.remove("zhangsan")
    println(list1)
    //不可变集合 to 可变集合
    val list3 : MutableList<String> = list.toMutableList()
    list3.add("xiaoxiao")
    list3.remove("zhangsan")
    println(list3)
    //可变集合 to 不可变集合
    val list4 : List<String> = list3.toList()

	//todo List集合遍历
    val list6 = listOf(1,2,3,4,5,6)
    //第一种遍历方式:
    for (i in list6){
        print("元素:$i   ")
    }
    println()
    //第二种遍历方式:
    list6.forEach {
        print("元素:$it   ")
    }
    println()

    //第三种遍历方式:
    list6.forEachIndexed{index,i ->
        print("下标:$index,元素:$i   ")
    }
    println()

2.mutator函数

    //mutator += -= 操作
    val list5 : MutableList<String> = mutableListOf("zhangsan","lisi")
    list5 += "mumu"
    list5 -= "zhangsan"
    println(list5)
    //removeIf
    //list5.removeIf(){ true } //如果是true全部删除掉
    list5.removeIf(){it.contains("li")} //过滤所有元素 只要包含li的元素就是true 删除
    println(list5)

3.kt语言的解构语法过滤元素学习

 val list7 :List<String> = listOf("张三","李四","赵武")
    val(v1,v2,v3) = list7
    println("v1:$v1,v2:$v2,v3:$v3")
    //用_内部可以不接受的赋值,可以节约一点性能
    val(_,value2,value3) = list7
    println("v2:$v2,v3:$v3")

    //todo set创建与元素获取
    //set集合不会出现重复元素,若出现则会被覆盖
    val set : Set<String> = setOf("zhangsan","lisi","zhaowu","zhangsan")
    println(set.elementAt(0))
    println(set.elementAt(1))
    println(set.elementAt(2))
    println(set.elementAtOrElse(3){"越界"})
    //OrNull + 空合并操作符 一起使用
    println(set.elementAtOrNull(10)?:"越界了")

4.可变set集合

    val set1 : MutableSet<String> = mutableSetOf("张三","李四")
    set1 += "木马"
    set1 += "小小"
    set1 -= "李四"
    println(set)

5.集合转换与快捷函数

    val list11 : MutableList<String> = 
    mutableListOf("zhangsan","zhangsan","lisi","xiaoxiao")
    //list 转 set 去重
    val set2 = list11.toSet()
    println(set2)
    //list转set转list去重
    val list12 = list11.toSet().toList()
    println(list12)
    //快捷去重 distinct
    println(list11.distinct()) //内部:县转换成可变的set集合 在转换成list集合 如下:
    println(list11.toMutableSet().toList())

6.数组类型

 	val intArray = intArrayOf(1,2,3,4,5)
    //越界崩溃
    println(intArray[0])
    println(intArray.elementAtOrElse(10){-1})
    println(intArray.elementAtOrNull(10) ?: "越界")
    //list集合转数组
    val charArray = listOf('A','B','C').toCharArray()
    //arrayOf
    val objArray = arrayOf<File>(File("AAA"),File("bbb"))

7.Map

//todo Map的创建
    val mMap1 : Map<String,Double> = 
    mapOf<String,Double>("Mumu" to(123.3),"xiaoxiao" to(234.4))
    val mMap2 : Map<String,Double> = 
    mapOf(Pair("Mumu",123.3), Pair("xiaoxiao",234.4))
    //读取Map的值
    //方式一
    println(mMap1["Mumu"])
    println(mMap1.get("Mumu")) //以上两个等价
    //方式二 getOrDefault
    println(mMap1.getOrDefault("xiaoxiao",-1))
    //方式三 getOrNull
    println(mMap1.getOrElse("Mumu"){-1})

    //todo Map遍历学习
    val map : Map<String,Double> = mapOf("zhangsan" to(12.22),"李四" to(3.14))
    //第一种方式
    map.forEach{
        println("K:${it.key},v:${it.value}")
    }
    //第二种方式
    map.forEach{key,value->
        println("key:$key,value:$value")
    }
    //第三种方式
    map.forEach{(k,v)->
        println("key:$k,value:$v")
    }
    //第四种方式
    for (item in map){
        println("key:${item.key},value:${item.value}")
    }

    //todo 可变的map集合
    val map1 : MutableMap<String,Int> = 
    mutableMapOf(Pair("zhangsan",123), Pair("lisi",111),Pair("xiaoxiao",555))
    map1 += "jj" to(656)
    map1 += "kk" to 999
    map1 -= "xiaoxiao"
    map1["CCC"] = 909
    map1.put("dd",898) //put 和 [] 等价
    //getOrPut 没有的情况
    //如果map1里没有ff的key元素,就先帮你添加到map集合里去,然后再从map1中获取
    val r :Int =map1.getOrPut("ff"){189}
    println(map1["ff"])
    map1.forEach{
        println("${it.key}:${it.value},")
    }
    //getOrPut 有的情况
    val r2 =map1.getOrPut("zhangsan"){909} //发现zhangsan的key是有的,就直接取出来,备用值909失效
    println(r2)

汇总五

1.field关键字的学习

class KtBase10(){
    var name="Muma"
    var value ="ABCD"
    //下面的隐式代码不写也有
        get()=field
        set(value){
            field=value
        }
    var info = "abcd is success"
        get()=field.capitalize()//把首字母改成大写
        set(value){
            field="**【$value】**"
        }
    /* 背后做的事
        @NotNull
        public final String getInfo() {
            return StringsKt.capitalize(this.info);
        }

        public final void setInfo(@NotNull String value) {
            Intrinsics.checkNotNullParameter(value, "value");
            this.info = "**【" + value + "】**";
        }

    */
}
//todo field关键字的学习
fun main(){
    //背后隐式代码:new KtBase10().setName("Xiaoxiao");
    KtBase10().name="Xiaoxiao"
    //背后隐式代码:System.out.println(new KtBase10().getName);
    println(KtBase10().name)
}

2.计算属性与防范竞态

class KtBase11(){
    val num : Int = 1
    /* 背后的代码
        private int num = 1
        public int getNum(){
            return this.num
        }
    */
    //计算属性 下面这样写 get函数覆盖了field内容 相当于field失效了
    val num1 : Int
        get()=(1..1000).shuffled().first() //从1到1000取出随机值 返回给getNum1()函数
    /* 背后隐式代码
        private int num2;
        public int getNum2(){
            return (1..1000).shuffled().first() java的随机逻辑
        }
    * */
    var info : String ?= ""//null
    //防范竞态条件 当你调用的成员可能为null 可能为空值 就必须采用防范竞态条件 这是KT的规范
    fun getShowInfo() : String {
        return info ?.let{
            if(it.isBlank()){
                "空值,请检查代码..."
            }else{
                "最终结果是:$it"
            }
        } ?: "null,请检查代码..."
    }
}
fun main(){
    //System.out.println(new KtBase11().getNum());
    println(KtBase11().num)

    //new KtBase11().setNum(9)
    //KtBase11().num=9 //val根本没有setNum()函数,只有getNum()函数

    println(KtBase11().num1)

    println(KtBase11().getShowInfo())
}

3.主构造函数

class KtBase12(_name:String,_sex:Char,_age:Int,_info:String){ //主构造函数
    var name = _name
        get() = field
        private set(value){
            field = value
        }
    val sex = _sex
        get() = field
    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 = KtBase12(_name = "Muma",_age = 17,_info = "学习Kotlin语言",_sex = '男')
    p.show()
}

4.主构造函数里定义属性

//var name :String  就相当于 var name = _name 只不过看不到而已
//一步到位
class KtBase13(val 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 = KtBase13(name="张三",sex='男',age=18,info="学习Kotlin语言")
    p.show()
}

5.次构造函数

 class KtBase14(name:String){ //主构造
    //2个参数的次构造函数,必须要调用主构造函数。为什么次构造必须调用主构造?主构造统一管理,为了更好的初始化设计
    constructor(name:String,sex:Char) : this(name){
        println("2个参数的次构造函数,name:$name,sex:$sex")
    }
    //3个参数的次构造函数
    constructor(name:String,sex:Char,age:Int) : this(name){
        println("3个参数的次构造函数,name:$name,sex:$sex,age:$age")
    }
    //4个参数的次构造函数
    constructor(name:String,sex:Char,age:Int,info:String) : this(name){
        println("4个参数的次构造函数,name:$name,sex:$sex,age:$age,info:$info")
    }
}
fun main(){
    val p = KtBase14("张三")
    KtBase14("张三",'男')
    KtBase14("李四",'女',18)
    KtBase14("小小",'女',19,"还在学习Kotlin语言")
}

6.初始化块学习

class KtBase15(username:String,userage:Int,usersex:Char){
    //初始化块 init代码块
    init{
        println("主构造函数被调用了,$username,$userage,$usersex")
        //如果第一个参数是false,就会调用第二个参数的lambda
        //判断username是不是空值 ""
        require(username.isNotBlank()){"你的username空空如也,异常"}
        require(userage > 0){"你的年龄不符合,异常"}
        require(usersex == '男' || usersex == '女'){"你的性别很奇怪,异常"}
    }
    constructor(username:String) : this(username,18, '男'){
        println("次构造函数被调用")
    }
}
fun main(){
    KtBase15("张三",19,'男') //调用主函数
    KtBase15("李四") //调用次函数
//    KtBase15("")
//    KtBase15("张三",-1,'男')
    KtBase15("张三",21,'k')
}

7.构造初始化顺序学习

//第一步生成val sex:Char
class KtBase16(_name : String,val sex : Char){
    //第二步生成val name
    val name=_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")
    }
}
fun main(){
    KtBase16("张三",'男',19)
}

8.延迟初始化lateinit

class KtBase17(){
    lateinit var responseResultInfo: String //等会再来初始化,先定义
    //模拟服务器加载
    fun loadRequest(){
        responseResultInfo = "恭喜,服务器加载成功"
    }
    fun showResponseResult() {
        if (::responseResultInfo.isInitialized) {
            println("responseResultInfo:$responseResultInfo")
        } else {
            println("你还没有初始化")
        }
    }
}
//todo 延迟初始化lateinit
fun main(){
    val p = KtBase17()
    //用到它才加载,就属于懒加载
    p.loadRequest()
    p.showResponseResult()
}

9.惰性初始化by lazy

class KtBase18(){
    //不使用惰性初始化 普通方式
//    val databaseData1=readSQLServerDatabaseAction()
    //使用惰性初始化,by lazy
    val databaseData2 by lazy{readSQLServerDatabaseAction()}
    private fun readSQLServerDatabaseAction(): String {
        println("开始读取数据库中...")
        println("加载数据库中...")
        println("结束读取数据库中...")
        return "database data load success ok."
    }
}
//todo 惰性初始化by lazy
//1、不使用惰性初始化:databaseData1=readSQLServerDatabaseAction()
//2、使用惰性初始化:databaseData2 by lazy
//3、KtBase18() 睡眠 db1.databaseData1
//lateinit 是在使用的时候 手动加载懒加载方式,然后在使用
//惰性初始化 by lazy 是在使用的时候,自动加载的懒加载方式,然后再使用
fun main(){
//    val p = KtBase18()
//    Thread.sleep(5000)
//    println("提示:${p.databaseData1}")
    val p = KtBase18()
    Thread.sleep(5000)
    println("提示:${p.databaseData2}")
}

10.继承与重载的open关键字学习

//默认的类,默认都是final修饰,不能被继承
open class Person(val name:String){
    private fun showName() = "父类 的姓名是【$name】"
    open fun myPrint() = println(showName())
}
class Student(private val subName : String) : Person(subName){
    private fun showName()="子类 的姓名是【${subName}】"
    override fun myPrint()= println(showName())
}
fun main(){
    val person : Person =Student("张三")
    person.myPrint()
}

汇总六

1.类型转换学习

open class Person2(val name:String){
    fun showName() = "父类 的姓名是【$name】"
    open fun myPrint() = println(showName())
    fun methodPerson()= println("父类方法..")
}
class Student2(private val subName : String) : Person2(subName){
    fun showName2()="子类 的姓名是【${subName}】"
    override fun myPrint()= println(showName2())
    fun methodStudent()= println("子类方法..")
}
fun main(){
    val p: Person2 =Student2("张三")
    p.myPrint()
    //检测类型
    println(p is Person2) //true
    println(p is Student2) //true
    //转换类型
    if(p is Student2){
        (p as Student2).myPrint()
    }
    if(p is Person2){
        println((p as Person2).showName())
    }
    //todo 智能类型转换
    (p as Student2).methodStudent()
    p.methodStudent()
    p.methodPerson()
    p.methodStudent()
}

2.Any超类学习

//在KT语言中,所有的类都隐式继承了 :Any(),你不写,默认就有
//Any类在KT语言设计中,只提供标准,看不到实现,实现在各个平台都实现好了
class Obj1 : Any()
class Obj2 : Any()
class Obj3 : Any()
class Obj4 : Any()
class Obj5 : Any()
fun main(){
    println(Obj1().toString())
}

3.对象声明

object KtBase28{
    init {
        println("KtBase28 init...")
    }
    fun show() = println("我是show函数")
}
fun main(){
    println(KtBase28)
    println(KtBase28)
    println(KtBase28)
    println(KtBase28.show())
}

4.对象表达式

interface RunnableKT{
    fun run()
}
open class KtBase29(){
    open fun add(info : String) = println("add:$info")
    open fun del(info : String) = println("del:$info")
}
fun main(){
    //匿名对象表达式方式
    val p : KtBase29 = object : KtBase29(){
        override fun add(info: String) {
//            super.add(info)
            println("我是匿名对象 add:$info")
        }
        override fun del(info: String) {
//            super.del(info)
            println("我是匿名对象 del:$info")
        }
    }
    p.add("张三")
    p.del("李四")
    //具名实现方式
    val p2 :KtBase29 = KtBase29Impl()
    p2.add("张具三")
    p2.del("李具四")
    //对Java的接口 用KT[对象表达式]
    val p3 =object : Runnable{
        override fun run() {
            println("Runnable run ...")
        }
    }
    p3.run()
    //对Java的接口 用Java最简洁的方式
    val p4 = Runnable {
        println("Runnable run2 ...")
    }
    p4.run()

    //对KT的接口 用KT[对象表达式]
    object : RunnableKT{
        override fun run() {
            println("RunnableKT run ...")
        }
    }.run()

    //小结:Java接口有两种方式,KT接口只有一种方式
}
//具名实现
class KtBase29Impl : KtBase29(){
    override fun add(info: String) {
//        super.add(info)
        println("我是具名对象 add:$info")
    }
    override fun del(info: String) {
//        super.del(info)
        println("我是具名对象 del:$info")
    }
}

5.伴生对象

class KtBase30{
    //伴生对象
    companion object{
        val info = "MumaInfo"
        fun showInfo()="显示:$info"
    }
}
//伴生对象的由来:在KT中没有java的这种static静态,伴生很大程度上和这种static差不多
//无论KtBase30()构建对象多少次,我们的伴生对象加载一次
//伴生对象只会初始化一次
fun main(){
    println(KtBase30.info)
    KtBase30.showInfo()
    KtBase30
    KtBase30
    KtBase30
}

6.嵌套类和内部类的学习

//内部类
//内部类的特点:内部的类 能访问 外部的类;外部的类 能访问 内部的类
class Body(_bodyInfo :String){
    val bodyInfo = _bodyInfo
    fun show(){
    }
    //默认情况下 内部的类不能访问外部的类,要增加inner修饰符,成为内部类才能访问外部类
    inner class Heart{
        fun run()= println("心脏访问身体信息:$bodyInfo")
    }
    inner class Hand{
        inner class leftHand{
            fun run()= println("左手访问身体信息:$bodyInfo")
        }
        inner class rightHand{
            fun run()= println("右手访问身体信息:$bodyInfo")
        }
    }
}
//嵌套类
//默认情况下就是嵌套类关系
//嵌套类特点:外部的类 能访问 内部的嵌套类;内部的类 不能访问 外部的成员
class Outer{
    val info :String = "OK"
    fun show(){
        Nested().inp()
    }
    class Nested{
        fun inp()= println("嵌套类")
    }
}
fun main() {
    //内部类
    Body("isOk").Heart().run()
    Body("isOk").Hand().leftHand().run()
    Body("isOk").Hand().rightHand().run()
    //嵌套类
    Outer.Nested().inp()
}

7.copy函数的学习

data class KtBase32(var name :String,var age : Int){ //数据类 主构造
    var coreInfo : String = ""
    init {
        println("主构造被调用")
    }
    constructor(name: String):this(name,99){
        println("次构造被调用")
        coreInfo="增加非常核心的内容信息"
    }
    override fun toString(): String {
        return "toString name:$name,age:$age,coreInfo:$coreInfo"
    }
}
//默认生成的toString、hashcode equals等..只管主构造,不管次构造
fun main() {
    val p1 = KtBase32("张三") //调用次构造
    println(p1)
    val p2 = p1.copy("李四",88)
    println(p2)
    //注意:使用copy的时候,由于内部代码只处理主构造,所以必须考虑次构造内容
}

8.解构声明学习

//普通类
class KtBase33(var name : String,var age : Int,var sex : Char){
    //顺序必须是和成员一一对应
    operator fun component1() = name
    operator fun component2() = age
    operator fun component3() = sex
}
//数据类
data class KtBase33Data(var name : String,var age : Int,var sex : Char)
fun main() {
    val(name,age,sex)=KtBase33("张三",78,'男')
    println("普通类解构后:name:$name,age:$age,sex:$sex")
    val(name1,age1,sex1)=KtBase33Data("李四",45,'男')
    println("数据类解构后:name1:$name1,age1:$age1,sex1:$sex1")
    val(name2,_,_)=KtBase33Data("李四",45,'男')
    println("数据类解构后:name2:$name2")
}

9.plus代表+运算符重载

data class AddClass(var num1:Int,var num2:Int){
    operator fun plus(p1:AddClass):Int{
        return (num1+p1.num1)+(num2+p1.num2)
    }
    //查看整个kt可以用的运算符重载方式
//    operator fun AddClass.
}
fun main() {
    //kt语言 plus代表+运算符重载
    println(AddClass(1,2)+AddClass(2,3))
}

10.枚举类定义函数

data class LimbsInfo(var limbsInfo: String, var length:Int){
    fun show(){
        println("${limbsInfo}的长度是:$length")
    }
}
enum class Limbs(private var limbsInfo: LimbsInfo){
    LEFT_HAND(LimbsInfo("左手",18)),
    RIGHT_HAND(LimbsInfo("右手",18)),
    LEFT_FOOT(LimbsInfo("左脚",26)),
    RIGHT_FOOT(LimbsInfo("右脚",26));

    fun show()="四肢是:${limbsInfo.limbsInfo},长度是:${limbsInfo.length}"
    fun updateData(limbsInfo: LimbsInfo){
        println("更新前的数据:${this.limbsInfo}")
        this.limbsInfo.limbsInfo=limbsInfo.limbsInfo
        this.limbsInfo.length=limbsInfo.length
        println("更新后的数据:${this.limbsInfo}")
    }
}
fun main() {
    //显示枚举值
    println(Limbs.LEFT_HAND.show())
    println(Limbs.RIGHT_HAND.show())
    println(Limbs.LEFT_FOOT.show())
    println(Limbs.RIGHT_FOOT.show())
    //更新枚举值
    Limbs.LEFT_FOOT.updateData(LimbsInfo("左脚更新",25))
}

汇总七

1.密封类

sealed class Exams(){
    object Fraction1 : Exams()
    object Fraction2 : Exams()
    object Fraction3 : Exams()
    class Fraction4(val studentName : String) : Exams()
}
class Teacher(private val exams: Exams){
    fun show() =
        when(exams){
            is Exams.Fraction1 -> "该学生分数很差"
            is Exams.Fraction2 -> "该学生分数及格"
            is Exams.Fraction3 -> "该学生分数良好"
            is Exams.Fraction4 -> "该学生分数优秀:该学生的名字是:${this.exams.studentName}"
        }
}
fun main() {
    println(Teacher(Exams.Fraction2).show())
    println(Teacher(Exams.Fraction4("张三")).show())
}

2.数据类型使用条件

data class LoginRequest(var info : String)
//todo 数据类型使用条件
//条件一:服务器请求回来相应的JavaBean、LoginResponseBean 基本上可以使用数据类
//条件二:数据类必须有一个参数的主构造函数
//条件三:数据类必须有参数,var val的参数
//条件四:数据类不能使用abstract、open、sealed、inner等修饰 (数据类,数据载入的事情、数据存输)
//条件五:需求 比较,copy、toString、解构等等,这些丰富的功能时也可以使用数据类

3.接口定义

interface IUSB{
    var usbVersionInfo:String //USB版本相关信息
    var usbInsertDavice:String //USB插入设备信息
    fun insertUSB() : String
}
//鼠标USB实现类
class Mouse(override var usbVersionInfo: String = "USB 3.0", override var usbInsertDavice: String = "鼠标接入USB口") : IUSB{
    override fun insertUSB() = "Mouse $usbVersionInfo,$usbInsertDavice"
}
//键盘USB实现类
class KeyBoard : IUSB{
    override var usbVersionInfo: String = "USB 3.1"
        get() = field
        set(value) {
            field=value
        }
    override var usbInsertDavice: String = "键盘接入了USB口"
        get() {
            println("get${field}的值出去了")
            return field
        }
        set(value) {
            field = value
            println("set${value}的值进来了")
        }
    override fun insertUSB(): String = "KeyBoard $usbVersionInfo,$usbInsertDavice"
}

//todo 接口定义
//1.接口里面的所有成员都是public open的,所以不需要open
//2.接口不能有主构造,没有构造
//3.实现类不仅仅要重写接口函数,还要重写接口成员
fun main(){
    val iusb1 : IUSB = Mouse()
    println(iusb1.insertUSB())

//    val iusb2 : IUSB = KeyBoard()
//    println(iusb2.insertUSB())
}

4.接口默认实现

interface USB2{
    //接口 var是不能给接口赋值的
    //任何类、接口等是不可以动态赋值的
    val usbVersionInfo : String
        get()=(1..1000).shuffled().last().toString()
        //val 不需要set
    val usbInsertDevice : String
        get()="高级设备接入USB"
    fun insertUSB() : String
}
class Mouse2() : USB2{
    override val usbVersionInfo: String
        get() = super.usbVersionInfo
    override val usbInsertDevice: String
        get() = super.usbInsertDevice
    override fun insertUSB() = "Mouse2 $usbVersionInfo,$usbInsertDevice"
}
//todo 接口默认实现
fun main(){
    val iusb = Mouse2()
    println(iusb.insertUSB())
}

5.定义泛型类

class KtBase40<T> (private  val obj : T){ //万能输出器
    fun show() = println("万能输出器:$obj")
}
data class Students(val name : String , val age : Int , val sex : Char)
data class Teachers(val name : String , val age : Int , val sex : Char)

fun main() {
    val stu1 = Students("张三",29,'男')
    val stu2 = Students("李四",19,'男')
    val tea1 = Teachers("赵武",12,'男')
    val tea2 = Teachers("刘柳",45,'男')

    KtBase40(stu1).show()
    KtBase40(stu2).show()
    KtBase40(tea1).show()
    KtBase40(tea2).show()
    KtBase40(String("小小".toByteArray())).show()
    KtBase40(23).show()
    KtBase40(23.4534).show()
    KtBase40(565.3f).show()
}

6.泛型函数学习

//万能对象返回器 Boolean控制是否返回,运用takeIf
class KtBase41<T>(private val isR : Boolean , private val obj : T){
    fun getObj() = obj.takeIf { isR }
}

//todo 泛型函数学习
fun main() {
    val stu1 = Students("张三",29,'男')
    val stu2 = Students("李四",19,'男')
    val tea1 = Teachers("赵武",12,'男')
    val tea2 = Teachers("刘柳",45,'男')
    println(KtBase41(true, stu1).getObj())
    println(KtBase41(true, stu2).getObj())
    println(KtBase41(true, tea1).getObj())
    println(KtBase41(true, tea2).getObj())
    println(KtBase41(false, tea2).getObj())

    //对象打印 + run + ?:
    KtBase41(true,stu1).getObj()?.run {
        println("万能对象是:$this")
    } ?: println("万能对象返回器,返回的是null")

    //对象打印 + apply + ?:
    //apply特点:永远返回getObj本身
    val r1 : Students = KtBase41(true,stu2).getObj()?.apply {
        if(this == null){
            println("万能对象返回器,返回的是null")
        }else{
            println("万能对象是:$this")
        }
    }!! //断崖
    println("r1:$r1")
    show1("张三")
    show1(12.22)
    show1(null)
}
//show(a : A) + also + ?
fun <A> show1(item : A){
    item?.also{
        println("万能对象是:$it")
    }?:println("万能对象返回器,返回的是null")
}

7.泛型变换实战

//模仿RxJava T是要变化的输入类型,R是变换后的输出类型
class KtBase42 <T> (val isMap : Boolean = false,val inputType : T){
    inline fun <R> map(mapAction:(T) -> R) = mapAction(inputType).takeIf { isMap }
}
inline fun <I , O> map(inputValue : I,isMap : Boolean = true,mapActionLambda : (I) -> O)=
    if (isMap) mapActionLambda(inputValue) else null
//todo 泛型变换实战
fun main() {
    val p1 = KtBase42(isMap = true,inputType = 123)
    val r1 : String? = p1.map {
        it.toString() //lambda最后一行是返回值
    }
    println(r1)
    //map Persons1->Student1 最终接收什么类型
    val p2 = KtBase42(true ,Persons1("张三",28))
    val r2 : Student1?=p2.map{
        it
        Student1(it.name,it.age)
    }
    println(r2)
    //map函数 模仿RxJava变换操作
    map(123){
        it.toString()
    }
    //todo 泛型类型的约束
    val per = personClass("张三")
    val son1 = son1Class("张大儿")
    val son2 = son2Class("张小儿")
    val dog = dogClass("其他")
    val a1 = KtBases(per).getObj()
    val a2 = KtBases(son1).getObj()
    val a3 = KtBases(son2).getObj()
    //val q1 = KtBases(dog).getObj() //其他类不兼容会报错

}
data class Persons1(val name : String , val age : Int)
data class Student1(val name : String , val age : Int)

//todo 泛型类型的约束
open class personClass (name:String) //父类
class son1Class(name:String) : personClass(name = name) //子类
class son2Class(name:String) : personClass(name = name) //子类
class dogClass(name : String) //其他类
//<A : personClass>:personClass本身 和personClass的所有子类都可以使用,其他的类,都不能兼容此泛型
class KtBases <A : personClass> (private val inputVal : A,private val isR: Boolean = true){
    //万能对象返回器
    fun getObj() = inputVal.takeIf { isR }
}

8.vararg关键字(动态参数)

//vararg val objects : T == val objects : List<T>
class KtBase43<T> (vararg val objects : T,var isMap : Boolean){
    //out T只能被读取,不能被修改
    val objectArray : Array<out T> = objects
    fun showObj(index : Int) : T? = objectArray[index].takeIf { isMap } /* objectArray[index] */
    fun <O> mapObj(index: Int,mapAction : (T?) -> O) = mapAction(objectArray[index].takeIf { isMap })
}

//todo vararg关键字(动态参数)
fun main() {
    //由于使用了太多的混合类型,所以使用Any?
    val p : KtBase43<Any?> = KtBase43("paul",12232,false,null,33.2,12.3f,isMap = true)
    println(p.showObj(0))
    println(p.showObj(1))
    println(p.showObj(2))
    println(p.showObj(3))
    println(p.showObj(4))
    println(p.showObj(5))

    val r : Int =p.mapObj(0){
        it.toString().length
    }
    println("第0个元素的字符串长度是:$r")

    val r1 : String = p.mapObj(1){
        "第1个元素是:$it"
    }
    println(r1)
}

10.运算符重载

class KtBase44 <INPUT> (vararg objects : INPUT,private val isR : Boolean = true){
    private val objectArray : Array<out INPUT> = objects
    //五种返回类型变化
    fun getR1() : Array<out INPUT>? = objectArray.takeIf { isR }
    //有可能是Array<out INPUT>,也有可能是String,用Any代替
    fun getR2() : Any = objectArray.takeIf { isR } ?: "是null"
    //有可能是Array<out INPUT>,有可能是String,也有可能是null,用Any?代替
    fun getR3() : Any? = objectArray.takeIf { isR } ?:"是null" ?:null

    fun getR4(index : Int) : INPUT? = objectArray[index].takeIf { isR } ?: null

    fun getR5(index: Int) : Any? = objectArray[index].takeIf { isR } ?:"张三" ?:123 ?:'k' ?:null

    //todo 运算符重载
    operator fun get(index : Int) : INPUT ? =objectArray[index].takeIf { isR }
}

fun <INPUT> inputObj (item : INPUT) {
    //泛型有很大的类型范围,可以接受很多类型,也可以接受null,但接收null要处理好
    //String? 可以接收字符串也可以接受null,要比String功能强大
    //小结:异步处理泛型接收,都用String?处理
    if(item is String?){
        println((item as String?)?.length ?: "传递的值为null")
    }else if(item is Int?){
        println((item as Int?)?.toString()?.length ?: "传递的值为null")
    }
}

fun main() {
    inputObj("张三")
    inputObj(123)
    inputObj(null)
    //todo []操作符学习
    val p : KtBase44<String?> = KtBase44("张三","李四",null)
    println(p[0])
    println(p[1])
    println(p[2])
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xx080

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值