Kotlin学习笔记(五)——继承、单例类等各种类的使用

小白笔记(持续更新中)

1.open: 移除final修饰(继承与重载)

//KT所有的类 默认是final修饰的,不能被继承
open class Test11(val name:String ) {
    fun showName(){println("父类  ${name}")}
    //KT所有的函数,默认是final修饰的,不能被重写
    open fun request(){showName() }
}

class Name (val subName:String):Test11(subName) {
    fun showName2(){println("子类  ${subName}")}
    override fun request(){showName2()}
}

fun main() {
    val person:Test11=Name("王五")
    person.request() //调用的是子类方法
}

2.强制类型转换

open class Person(val name:String) {
    fun showName(){println("父类  ${name}")}
    open fun request(){showName() }
}
class Student (val subName:String):Person(subName) {
    fun showName2(){println("子类  ${subName}")}
    override fun request(){showName2()}
}
fun main() {
    //父类引用子类对象
    val p:Person= Student("王五")
    //判断p是否为Person类型  返回true/false
    println(p is Person)
    //由于p为Person类型,不能调用Student的独有方法
    //p.showName2()   报错
    //将p强制转换为Student类型
    (p as Student).showName2() //将Person类型转换为Student类型,可以调用Student的独有方法
}

3.智能类型转换

open class Person1(val name:String) {
    fun showName(){println("父类  ${name}")}
    open fun request(){showName() }
}
class Student1 (val subName:String):Person1(subName) {
    fun showName2(){println("子类  ${subName}")}
    override fun request(){showName2()}
}
fun main() {
    val person:Person1=Student1("王五")
    //if内部 做了智能类型转换,person为Student1类型,可以调用它的独有方法
    if (person is Student1){
        //Smart cast to fivecontent.Student1  智能转换类型根据 is 后的类型转换
        person.showName2()
        //没有提示做了智能转换
        person.showName()
    }
    //val person: Person1  类型不为Student1  无法调用它的独有方法
    //person.showName2()

    //一般is + as 一起使用进行类型转换
    if (person is Person1){
        //此时person的智能转换类型为Person1 无法调用Student1的独有方法
        //person.showName2()  //报错
        //用as将Person1转换为Student1类型,可以调用Student1的独有方法
        (person as Student1).showName2()
    }
}

4.Any超类

//KT中,所有的类都隐式继承了 :Any()  默认就有,可以不写
//Any类在KT设计中: 只提供标准,你看不到实现,实现在各个平台处理好了  例如:Window等等
class Test04 :Any() {
}
// Any==java Object
fun main() {
    println(Test04().toString())
}

5.object 类名 {} 对象声明(单例)

//private Test05() {}  主构造方法私有化,所以不加()
object Test05 {
    //static {
    //      Test05 var0 = new Test05();
    //      INSTANCE = var0;
    //      String var1 = "init....";
    //      System.out.println(var1);
    //   }
    //主构造方法私有化,init内容在static静态代码块中执行
    //静态代码块中还执行单例INSTANCE的初始化
    init {
        println("init....")
    }
    fun show()= println("我是show函数")
}
fun main() {
    //Test05  背后代码:Test05.INSTANCE
    //既是单例的实例,又是类名,只有一个创建,这就是典型的单例
    println(Test05)  //fivecontent.Test05@7f63425a
    println(Test05)  //fivecontent.Test05@7f63425a
    println(Test05)  //fivecontent.Test05@7f63425a
    println(Test05)  //fivecontent.Test05@7f63425a
    //Test05.show()  背后代码:Test05.INSTANCE.show()
    println(Test05.show())
}

6.对象表达式 object:父类()/接口 {}(new子类/实现类对象的一种方式)

//Kt接口
interface RunnableKt{
    fun run(){}
}
open class Test06 {
    open fun add(){}
    open fun del(){}
}
fun main() {
    //匿名对象表达式方式  类似于Java中的匿名内部类
    //object:Test06() 继承了Test06
    //父类引用子类对象
    val test:Test06=object:Test06(){
        override fun add() {
           println("我是add")
        }
        override fun del() {
            println("我是del")
        }
    }
    test.add()
    test.del()

    //具名实现方式
    //父类引用子类对象
    val test1:Test06=Test06Impl("王五")
    test1.add()
    test1.del()

    //对Java的接口 使用对象表达式方式
    val runnable=object :Runnable{
        override fun run() {
            println("执行run方法......")
        }
    }
    runnable.run()
    //对Java接口 使用java lambda
    val runnable1=Runnable { println("执行run方法......") }
    runnable1.run()

    //对Kotlin接口 使用对象表达式
    object :RunnableKt{
        override fun run() {
            println("执行kotlin run方法......")
        }
    }.run()

    //对kotlin接口 使用Java lambda  不可以使用 会报错
    //RunnableKt{ println("执行kotlin run 方法")}
}
class Test06Impl(val name:String):Test06(){
    override fun add() {
        println("我是add")
    }
    override fun del() {
        println("我是del")
    }
}

7.伴生对象 companion object{}(类似于Java中的static)

//在KT中没有Java里的static静态  伴生对象很大程度上与Java的static静态相同的
class Test07 {
    //public static final Test07.Companion Companion
    //静态不可变对象(静态单例)
    companion object{
        //private static (final) String info = "信息";
        //私有静态属性
        val info="信息"
//        var info="信息"
        fun show(){"开始展示"}
    }
}
fun main() {
    println(Test07.info)
    println(Test07.show())
}

8.inner class 内部类 与 嵌套类(在class中的class)

//内部类可以访问外部类(属性 方法)
class Test08 {
    //背后的代码: public static final class NeiBuLei
    //inner 移除了static 使得NeiBuLei由外部类变为了内部类
    //外部类要想成为内部类 需要用inner修饰去掉static
    val name="内部类"
    fun show(){NeiBuLei().run()}
    fun showage(){NeiBuLei().age}
    //内部类
    inner class NeiBuLei{
        //内部类中不能有静态字段和静态方法
//        companion object{}
        val age=5
        fun run()= println(name)
        fun showNei()=show()
    }
}
//嵌套类不能直接调用外部类的非静态成员属性
class Wai(){
    val name2="嵌套类的外部类"
    fun showQian()=QianTao().name1
    companion object{
        val name3="嵌套类的外部类"
    }
    class QianTao(){
        val name1="嵌套类"
        fun show()=Wai().showQian()
//        fun showName1()= println(name2)  报错
        fun showName()= println(name3)
    }
}

fun main() {
    //内部类的调用方式,因为内部类不是静态类
    Test08().NeiBuLei().showNei()
    //嵌套类的调用方式 因为嵌套类是静态类
    Wai.QianTao().showName()
}

9.data class 类名(){} 数据类

//普通类 包含属性 get/set函数 构造函数
class JavaBean(var name:String,val age:Int,val data:String ) {}
//数据类 包含属性 get/set函数 构造函数 解构操作 copy toString hashCode equals
data class JavaBean1(var name:String,val age:Int,val data:String ) {}

fun main() {
    val bean1 = JavaBean("f", 78, "ff")
    println(bean1)
    val bean2 = JavaBean("f", 77, "ff")
    println(bean2)
    //比较的是值
    println(bean1==bean2)
    //比较的是引用是否相同
    println(bean1===bean2)

    val bean3 = JavaBean1("f", 78, "ff")
    //数据类有自己的toString()方法
    println(bean3)
    val bean4 = JavaBean1("f", 77, "ff")
    println(bean4)
    //比较的是参数的值是否相同  不相同返回false
    println(bean3==bean4)
    //比较的是引用是否相同
    println(bean3===bean4)
}

10.copy函数

data class Test10(val name:String,val data:String) {
    var age=0
    constructor(name:String):this(name,"xiao"){
        age=55
    }
    //重写toString方法
    override fun toString(): String {
        return "name:$name age:$age"
    }
}

fun main() {
    val p=Test10("小刘","小刘")
    println(p)
    //copy函数返回一个调用主构造函数创建的本类实例对象(与次构造方法无关)
    val person=p.copy("小六","小刘")
    println(person)
    //这里的比较还是做为数据类的比较  比较方式:比较参数的值是否相同
    //值不相同的返回false
    println(person==p)

    //次构造函数中初始化了age的值 所以为55
    val test10 = Test10("小刘")
    println(test10)
    //copy没有用到次构造函数,所以age为0
    val test=test10.copy("小七","小八")
    println(test)
}

11.解构声明 从component1开始

class Test11 (val name:String,val age:Int,val sex:Char) {
    //operator 运算符重载
    //解构声明  必须从component1开始按顺序声明,不能从component0开始声明
    operator fun component1()=name
    operator fun component2()=age
    operator fun component3()=sex
}
//数据类
data class CopyClass (val name:String,val age:Int,val sex:Char) {}

fun main() {
    val(name,age,sex)=Test11("小刘",55,'女')
    val(name1,age1,sex1)=CopyClass("小刘",55,'女')
    println("name:$name age:$age sex:$sex")
    println("name:$name1 age:$age1 sex:$sex1")
    //_拒接收对应数据
    val(_,age2,_)=CopyClass("小巴",78,'男')
    println("age:$age2")
}

12.运算符重载 operator

class Test12 (val number1:Int,val number2:Int) {
    //加法
    operator fun plus(p1:Test12):Int{
        return (number1+number2)+(p1.number1+p1.number2)
    }
}
fun main() {
    //Java代码:int var0 = (new Test12(5, 10)).plus(new Test12(10, 20));
    println(Test12(5,10)+Test12(10,20))
}

13.枚举类 enum class 类名{}

//KT想表达: 枚举其实也是一个class
enum class Week {
    星期一,
    星期二,
    星期三,
    星期四,
    星期五,
    星期六,
    星期日;
}
fun main() {
    println(Week.星期五)
    println(Week.星期三)
    //枚举的值  等价于 枚举类本身
    println(Week.星期六 is Week)  //true
}

14.枚举类中定义函数

class People(var name:String,var number:Int){}
enum class PeopleEnum(private var people:People) {
    //枚举值括号里的参数要与主构造函数的入参保持一致
    RIGHT_HAND(People("右手",80)),
    LEFT_HAND(People("左手",80)),
    RIGHT_FOOT(People("右脚",160)),
    //枚举要以 ; 结尾
    LEFT_FOOT(People("左脚",160));

    fun show(){
        println("部位:${people.name},长度:${people.number}")
    }

    fun updateInfo(people2: People){
        this.people.number=people2.number
        this.people.name=people2.name
        println("更新后: 部位:${people.name},长度:${people.number}")
    }
}
fun main() {
    //枚举类调用方法
    PeopleEnum.LEFT_HAND.show()
    //枚举更新信息的方法
    PeopleEnum.LEFT_HAND.updateInfo(People("左腿",56))
}

15.代数数据类型

enum class Stu{
    Level1,
    Level2,
    Level3,
    Level4,
    Level5;
}
class Test15(private val stu: Stu) {
    fun show():String {
        return when (stu) {
            Stu.Level1 -> "等级1"
            Stu.Level2 -> "等级2"
            Stu.Level3 -> "等级3"
            Stu.Level4 -> "等级4"
            Stu.Level5 -> "等级5"
            //else-> 由于我们的show函数,是使用枚举类类型来做判断处理的,这个就属于 代数数据类型 就不需要写else了
        }
    }
}
fun main() {
    println(Test15(Stu.Level4).show())
}

16.密封类 sealed class 类名{}

密封类本身是 abstract 的:它不能直接实例化,可以有抽象(abstract) 成员。
不允许有 非 private修饰的构造函数(其构造函数默认是 private)
扩展密封类的类(子类)必须与密封类在同一文件中
扩展密封类子类的类(间接继承者)可以放在任何位置,而无需在同一个文件中

//密封类的构造函数默认是private
//Java: public abstract class Level   abstract修饰类,Level不能被实例化
sealed class Level {
    //都要继承密封类
    //object Level1 Level2都不需要任何成员 所以一般写成object
    object Level1:Level()
    object Level2:Level()
    //Level3 有成员属性 可以创建不同的实例对象 所以用object不合理 用class合理
    class Level3(val levelName:String):Level()
}
class Test16(private val level: Level){
    fun show():String{
        return when(level){
            is Level.Level1->"等级一"
            is Level.Level2->"等级二"
            //is判断是否这个类型  this.level会智能转换类型为对应的类型 不需要再用as做类型转换
            is Level.Level3->"这个等级级别为: ${(this.level as Level.Level3).levelName}"
        }
    }
}
fun main() {
    println(Test16(Level.Level1).show())
    println(Test16(Level.Level2).show())
    println(Test16(Level.Level3("等级三")).show())
}

17.数据类使用条件

条件一: 服务器请求回来的响应的JavaBean LoginResponseBean 基本上可以使用 数据类
条件二: 数据类至少必须有一个参数的主构造函数
条件三: 数据类必须有参数 var val 的参数
条件四: 数据类不能使用 abstract open sealed inner 等等修饰
条件五: 有这些需求的: 比较 copy toString 解构 等等 可以使用数据类

   data class Test17(val name:String) {}

如有不对的地方,欢迎小伙伴指出哈!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值