1、Kotlin 继承open关键字

//TODO Kotlin 基础与重载的open关键字

//所有的类默认是final修饰的,不能被继承与Java相反
//加open相当于移除final
open class Person(val name:String){

    private fun showName() = "人类的名字是[$name]"

    //所有的函数默认也是final修饰,不能被重写
    open fun myPrintlin() = println(showName())

}

class Student(val subName:String) : Person(subName){

    private fun showName() = "子类的姓名是[$subName]"

    override fun myPrintlin() = println(showName())

}

fun main() {
    val person:Person = Student("张三")
    person.myPrintlin()
}

2、Kotlin 类型转换

//TODO Kotlin 类型转换
import java.io.File
//所有的类默认是final修饰的,不能被继承与Java相反
//加open相当于移除final
open class Person(val name: String) {

    fun showName() = "人类的名字是[$name]"

    //所有的函数默认也是final修饰,不能被重写
    open fun myPrintlin() = println(showName())

}

class Student(val subName: String) : Person(subName) {

    fun showName2() = "子类的姓名是[$subName]"

    override fun myPrintlin() = println(showName2())

}

fun main() {
    val p: Person = Student("王五")
    p.myPrintlin()

    println(p is Person)

    println(p is Student)

    println(p is File)

    //is +as

    if (p is Student) {
        (p as Student).myPrintlin()
    }

    if (p is Person) {
//        (p as Person).myPrintlin()
        println((p as Person).showName())
    }
}

3、Kotlin智能转换

import java.io.File

//TODO Kotlin 智能类型转换

//所有的类默认是final修饰的,不能被继承与Java相反
//加open相当于移除final
open class Person(val name:String){

    fun showName() = "人类的名字是[$name]"

    //所有的函数默认也是final修饰,不能被重写
    open fun myPrintlin() = println(showName())

    fun methodPerson() = println("我是父类的方法...")

}

class Student(val subName:String) : Person(subName){

    fun showName2() = "子类的姓名是[$subName]"

    override fun myPrintlin() = println(showName2())
    fun methodStudent() = println("我是子类的方法...")

}

fun main() {
    val p:Person = Student("王五")

    //is +as

    (p as Student).methodStudent()
    //根据上面P as 说明已经转过的类型,下面可以直接调用子类的方法
    p.methodStudent()

}

4、Kotlin 中Any类

//TODO Kotlin Any超类 相当于Java 的Object

//在Kotlin中类隐式继承了Any(),不写,默认也有
//Any 设计中,只提供标准,看不到实现
class obj1:Any()

fun main() {

    println(obj1().toString())

}

只提供标准,不会进行实现

5、Kotlin Object

object KtBase {
    /*
    object 类 背后做了什么?

    public static final KtBase INSTANCE;

    private KtBase(){} //主构造废除一样的效果

    public final void show(){
        String var1 = "我是show函数";

        ...

        System.out.println(var1)

    }

    //这个区域是object不同点

    static{

        KtBase var0 = new KtBase();
        INSTANCE = var0;
        String var1 = "KtBase init..."
        System.out.println(var0)
    }

     */

    init {
        println("KtBase init...")
    }

    fun show() = println("我是show函数")

}

fun main() {
    // object KtBase既是单例的实类,也是类名
    //小结: 既然是单例的实例,又是类名,只有一个创建,这就是典型的单例

    println(KtBase) // 背后代码println(KtBase.INSTANCE)
    println(KtBase)
    println(KtBase)

    //不需要带() KTBase.INSTANCE
    println(KtBase.show())
}

INSTANCE在静态代码块里进行初始化

6、Kotlin对象表达式

open class KtBase {

    open fun add(info: String) = println("add:$info")

    open fun del(info: String) = println("del:$info")

}

//具名方式实现
class KTBase1 : KtBase() {
    override fun add(info: String) {
//            super.add(info)
        println("我是具名对象add:$info")
    }

    override fun del(info: String) {
//            super.del(info)
        println("我是具名对象del:$info")
    }
}
fun main() {
    //匿名对象表达式
    val p = object : KtBase() {
        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 = KTBase1()
    p2.add("李元霸")
    p2.del("李连杰")

    //java 接口方式
    val p3 = object :Runnable {
        override fun run() {
            println("Runnable run ..")
        }
    }
    p3.run()

    //java最简洁方式
    val p4 = Runnable {
        println("Runnable run2 ..")
    }
    p4.run()
}

7、Kotlin 伴生对象

//TODO Kotlin 伴生对象

class KtBase {

    //伴生对象由来:Kotlin中没有static静态,伴生很大程度上和Java的这种static静态差不多
    companion object {
        val info = "testInfo"
        fun showInfo() = println("显示:$info")
    }
    /* companion object{} 背后逻辑
     private static final String info = "testInfo";
     public static final KtBase.Companion campoanion = new Companion();

     */
}

//伴生对象只会初始化一次

fun main() {
    //背后代码 KtBase.Companion.getInfo
    println(KtBase.info)
    //背后代码 KtBase.Companion.showInfo()
    KtBase.showInfo()

    //new KtBase() ,无论构建多少次,伴生对象只有一次
    KtBase()
    KtBase()
    KtBase()
    KtBase()
}

8、Kotlin 内部类inner与嵌套类

//TODO Kotlin 嵌套类 和内部类

//内部类特点 :内部类能访问外部的类
//外部的类 能访问内部的类,加inner修饰符
class Body(_bodyInfo: String) {

    val bodyInfo = _bodyInfo

    //默认情况下:内部类不能访问外部类,要加修饰符称为内部类,才可以访问外部类
    inner class Heart {
        fun run() = println("心脏访问身体信息:$bodyInfo")
    }

    inner class Kidney {
        fun work() = println("肾脏访问身体信息:$bodyInfo")
    }

    inner class Hand {
        inner class LeftHand {
            fun work() = println("左手访问身体信息:$bodyInfo")
        }

        inner class RightHand {
            fun work() = println("右手肾脏访问身体信息:$bodyInfo")
        }
    }
}

//嵌套类,默认情况下是嵌套类
//嵌套类特点:外部的类 能访问内部的类 ,嵌套类不能访问内部外部类的成员
class Outer {

    val info = "ok"

    fun show() {
        Nested().output()
    }

    class Nested {
        fun output() = println()

    }
}

fun main() {
    //内部类
    Body("isOk").Heart().run()
    Body("isOk").Hand().LeftHand().work()

    //嵌套类
    Outer.Nested().output()
}

9、Kotlin数据类data 修饰

//普通类
//生成的只有普通变量,set get方法
class ResponseResultBean(var msg: String, var code: Int, var data: String)

//数据量 ,一般情况下用于javaBean
//除了生成普通变量,set get方法,还有hashCode,equals(),解构操作,toString()
//数据类生成的方法更多
data class ResponseResultBean2(var msg: String, var code: Int, var data: String)

fun main() {

    //val (v1,v2,v3) = list

    //ResponseResultBean@610455d6 ,调用Any.toString(),只提供标准,windows实现打印的
    println(ResponseResultBean("loginSuccess", 200, "登录成功的数据"))

    //data 数据类,额外生成toString(),重写了父类的toString()函数
    //ResponseResultBean2(msg=loginSuccess, code=200, data=登录成功的数据)
    println(ResponseResultBean2("loginSuccess", 200, "登录成功的数据"))

    println()

    // == 值得比较,===引用的比较

    // == Any的父类 由平台实现,由两个对象引用进行比较,所以返回false
    println(
        ResponseResultBean("loginSuccess", 200, "登录成功的数据") ==
                ResponseResultBean("loginSuccess", 200, "登录成功的数据")

    )

    // == Any的父类 ,会重写父类的equals,进行的值得比较,返回为true
    println(
        ResponseResultBean2("loginSuccess", 200, "登录成功的数据") ==
                ResponseResultBean2("loginSuccess", 200, "登录成功的数据")

    )

}

Kotlin 数据类data使用场景

1:服务器请求回来的响应 JavaBean 基本上可以使用数据类

2、条件类至少必须有一个参数的主构造函数

3、数据类必须有参数, var val 的参数

4、 数据类不能使用abstract ,不能open saled ,inner等等修饰, 数据类只做数据载入的事情

5、需求; 比较,copy. toString,结构等丰富功能,可以使用数据类

10、Kotlin copy函数

//TODO Kotlin copy函数

data class KtBase(var name: String,var age :Int){

    var coreInfo:String = ""

    //次构造
    constructor(name: String) :this(name,99){
        println("次构造被调用")
        coreInfo = "增加非常核心的内容信息"
    }

    override fun toString(): String {
        return "toString name:$name,age:$age,coreInfo:$coreInfo"
    }

}

/*
//默认生成的toString ,hashCode(),equals(),只管主构造,不管次构造
@NotNull
public String toString() {
    return "KtBase(name=" + this.name + ", age=" + this.age + ")";
}
*/

fun main() {
    val p1 = KtBase("李元霸")//调用次构造初始化

    println(p1)

    val newP2 = p1.copy("李连杰",78)
    println(newP2)

    // copy toString hashCode equals
    //注意事项:使用copy时,只考虑主构造,copy调用的也是主构造, 必须考虑次构造内容
}

11、Kotlin 解构函数

//TODO Kotlin 解构声明  component
//数据类自己就解构

class Student(var name:String,var age:Int,var sex:Char){

    //注意:顺序必须是component1 ,component2 ,component3 和成员一一对应
    operator fun component1() = name
    operator fun component2() = age
    operator fun component3() = age
}

/*
//默认生成的toString ,hashCode(),equals(),只管主构造,不管次构造
@NotNull
public String toString() {
    return "KtBase(name=" + this.name + ", age=" + this.age + ")";
}
*/

data class Student2(var name:String,var age: Int,var sex: Char)

fun main() {
    val(name,age,sex) = Student("李四",89,'男')
    println("普通类 解构后:name:$name,age:$age,sex:$sex")

    val(name1,age1,sex1) = Student2("李四",89,'男')
    println("数据类 解构后:name:$name1,age:$age1,sex:$sex1")

    val (_,age2,_) = Student("李四",89,'男')
    println("数据类 解构后:age:$age2")

}

12、Kotlin 运算符重载

//TODO Kotlin 运算符重载

class AddClass(number1:Int,number2:Int)

data class AddClass2(var number1: Int,var number2: Int){
    operator fun plus(p1:AddClass2) : Int{
        return (number1+p1.number1) + (number2 + p1.number2)
    }

}

fun main() {

    //运算符重载 C++ 里 +
    //KT中plus代表+
//    AddClass2(1,1)+AddClass2(2,2)
    println( AddClass2(1,1)+AddClass2(2,2))

}

查看所有可用的运算符重载

13、Kotlin 中枚举

//枚举也是一个class
enum class Week {
    星期一,
    星期二,
    星期三,
    星期四,
    星期五,
    星期六,
    星期日

}

//枚举类学习
fun main() {

    //枚举的值等价于枚举本身
    println(Week.星期一)
    println(Week.星期五)

    println(Week.星期二 is Week)
}

14、Kotlin中枚举详细使用

//TODO Kotlin 枚举类详细使用

data class LimbsInfo(var LimbsInfo:String,var length: Int){
    fun show(){
        println("${LimbsInfo}的长度是:$length")
    }
}

//枚举是一个class,就是为了枚举有更好的功能
enum  class Limbs(private var limbsInfo: LimbsInfo){
    LETF_HAND(LimbsInfo("左手",88)),//左手
    RIGHT_HAND(LimbsInfo("右手",88)),//右手

    LETF_FOOT(LimbsInfo("左脚",88)),//左脚
    RIGHT_FOOT(LimbsInfo("右脚",88))//右脚
    ;//结束枚举值

    // 1、WEEK() 这时候再定义单调的枚举值,就报错了,必须所有枚举值,保持一致效果
    //2、枚举主构造的参数必须和枚举(参数) 保持一致

    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().show())
    println(Limbs.show())*/

    //一般用法如下
    println(Limbs.LETF_HAND.show())
    println(Limbs.RIGHT_HAND.show())
    println(Limbs.LETF_FOOT.show())
    println(Limbs.RIGHT_FOOT.show())

    //更新枚举值
    Limbs.RIGHT_HAND.updateData(LimbsInfo("右手2",99))
    Limbs.LETF_FOOT.updateData(LimbsInfo("左脚2",99))

}

//TODO Kotlin 枚举类详细使用

enum class Exam{
    Eraction1,//分数差
    Eraction2,//分数及格
    Eraction3,//分数良好
    Eraction4,//分数优秀
    ;//枚举结束

    //得到优秀学生的名字 ,枚举类做到此需求,很麻烦 //引出密封类
    var studentName:String? = null
}

class Teacher(private val exam: Exam){
    fun show() :String=
        when(exam){
            Exam.Eraction1 -> "该学生分数很差"
            Exam.Eraction2 -> "该学生分数及格"
            Exam.Eraction3 -> "该学生分数良好"
            Exam.Eraction4 -> "该学生分数优秀"
            //else -> 由于show函数是使用枚举类型来判断处理,这个属于代数数据类型,不需要写else
            //因为when表达式很明确,就这四种类型,不会出现其他,所以可以不写

        }

}

//枚举类学习
fun main() {

    println(Teacher(Exam.Eraction1).show())
    println(Teacher(Exam.Eraction3).show())

}

15、Kotlin密封类

import sun.security.util.Length
import kotlin.math.E

//TODO Kotlin 密封类详细使用
//密封类成员 必须有类型且继承本类 sealed

sealed class Exam {
    //不需要任何成员,写成object
    object Eraction1 : Exam()//分数差
    object Eraction2 : Exam()//分数及格
    object Eraction3 : Exam()//分数良好

    class Eraction4(val studentName2: String) : Exam()//分数优秀

    //得到优秀学生的名字 ,枚举类做到此需求,很麻烦 //引出密封类
    var studentName: String? = null
}

class Teacher(private val exam: Exam) {
    fun show(): String =
        when (exam) {
            is Exam.Eraction1 -> "该学生分数很差"
            is Exam.Eraction2 -> "该学生分数及格"
            is Exam.Eraction3 -> "该学生分数良好"
            is Exam.Eraction4 -> "该学生分数优秀:该学生的姓名是:${(this.exam as Exam.Eraction4).studentName2}"
            else -> " error"
        }

}

//枚举类学习
fun main() {

    println(Teacher(Exam.Eraction1).show())
    println(Teacher(Exam.Eraction2).show())
    println(Teacher(Exam.Eraction3).show())
    println(Teacher(Exam.Eraction4("李四")).show())
    println(Teacher(Exam.Eraction4("王五")).show())

    println(Exam.Eraction1 === Exam.Eraction1)
    println(Exam.Eraction4("AAA") === Exam.Eraction4("AAA")) //class 有两个不同的对象是false,不是object
}

作者:胖胖狼
链接:https://juejin.cn/post/7101308364562366471

加客服微信:qiushu0517,开通VIP下载权限!