Kotlin基础语法五

  • 继承与重载的open关键字

    KT所有的类,默认是final修饰的,不能被继承,和Java相反

    open:移除final修饰

  • 类型转换

    open class Person2(private val name: String) {

    复制代码
      fun showName() = "父类 的姓名是【$name】"
    
      // KT所有的函数,默认是final修饰的,不能被重写,和Java相反
      open fun myPrintln() = println(showName())

    }

    class Student2(private val subName: String) : Person2(subName) {

    复制代码
      fun showName2() = "子类 的姓名是【${subName}】"
    
      override fun myPrintln() = println(showName2())

    }

    // TODO 84.Kotlin语言的类型转换学习
    // 1.普通运行子类输出
    // 2.is Person Student File
    // 3.is + as 转换
    fun main() {
    val p: Person2 = Student2("王五")
    p.myPrintln()

    复制代码
      println(p is Person2)
      println(p is Student2)
      println(p is File)
    
      // is + as = 一般是配合一起使用
      if (p is Student2) {
          (p as Student2).myPrintln()
      }
    
      if (p is Person2) {
          // (p as Person2).myPrintln() // 因为子类重写了父类
          println((p as Person2).showName())
      }

    }

  • 智能类型转换

    open class Person3(val name: String) {
    private fun showName() = "父类显示:$name"

    复制代码
      open fun myPrintln() = println(showName())
    
      fun methodPerson() = println("我是父类的方法...") // 父类独有的函数

    }

    class Student3(val nameSub: String) : Person3 (nameSub) {
    override fun myPrintln() = println("子类显示:$nameSub")

    复制代码
      fun methodStudent() = println("我是子类的方法...") // 子类独有的函数

    }

    fun main() {
    val p : Person3 = Student3("李四")

    复制代码
      (p as Student3).methodStudent()
    
      p.methodStudent()
      // 智能类型转换:会根据上面 as 转成的类型,自动明白,你现在的类型就是上面的类型

    }

  • Any超类

    所有的类都默认继承Any超类,等于Java的Object

  • 对象声明 object

  • 对象表达式

    interface RunnableKT {
    fun run()
    }

    open class KtBase88 {
    open fun add(info: String) = println("KtBase88 add:info") open fun del(info: String) = println("KtBase88 del:info")
    }

    // 1.add del println
    // 2.匿名对象表达式方式
    // 3.具名实现方式
    // 4.对Java的接口 用对象表达式方式
    fun main() {
    // 匿名对象 表达式方式
    val p : KtBase88 = object : KtBase88() {

    复制代码
          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 = KtBase88Impl()
      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()
    
      // 对KT的接口 用   Java最简洁的方式 方式二
      /*RunnableKT {
    
      }*/

    }

    // 小结:Java接口,有两种方式 1(object : 对象表达式) 2简洁版,
    // KT接口,只有一种方式 1(object : 对象表达式)

    // 具名实现 具体名字 == KtBase88Impl
    class KtBase88Impl : KtBase88() {

    复制代码
      override fun add(info: String) {
          // super.add(info)
          println("我是具名对象 add:$info")
      }
    
      override fun del(info: String) {
          // super.del(info)
          println("我是具名对象 del:$info")
      }

    }

  • 伴生对象

    // 伴生对象的由来: 在KT中是没有Java的这种static静态,伴生很大程度上和Java的这种static静态 差不多的
    // 无论 KtBase89() 构建对象多少次,我们的伴生对象,只有一次加载
    // 无论 KtBase89.showInfo() 调用多少次,我们的伴生对象,只有一次加载
    // 伴生对象只会初始化一次

    复制代码
      companion object {
          val info = "UserInfo"
          fun showInfo() = println("显示:$info")
          val name = "Derry"
      }
  • 内部类 & 嵌套类

    // TODO 内部类
    // 内部类的特点: 内部的类 能访问 外部的类
    // 外部的类 能访问 内部的类
    class Body(_bodyInfo: String) { // 身体类

    复制代码
      val bodyInfo = _bodyInfo
    
      fun show() {
          Heart().run()
      }
    
      // 默认情况下:内部的类 不能访问 外部的类,要增加修饰符inner 成为内部类才可以访问外部类
      inner class Heart { // 心脏类
          fun run() = println("心脏访问身体信息:$bodyInfo")
      }
    
      inner class Kidney { // 肾脏
          fun work() = 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().output()
    }

    复制代码
      class Nested {
          fun output() = println("嵌套类")
      }

    }

    fun main() {
    // 内部类:
    Body("isOK").Heart().run()
    Body("isOK").Hand().LeftHand().run()
    Body("isOK").Hand().RightHand().run()

    复制代码
      // 嵌套类:
      Outer.Nested().output()

    }

  • 数据类

    // set get 构造函数 解构操作 copy toString hashCode equals 数据类 生成 更丰富
    data class ResponseResultBean2(var msg: String, var code: Int, var data: String) : Any()

  • copy

    // 深拷贝 重新创建对象
    data class User(val name: String)
    val a = User("Alice")
    val b = a.copy()
    println(a === b) // 输出 false

    //浅拷贝 复用同一个对象
    data class Book(val title: String)
    data class User(val name: String, val book: Book)

    val u1 = User("Bob", Book("Kotlin"))
    val u2 = u1.copy(name = "Alice")
    u2.book.title = "Java" // 会同时修改u1.book

  • 解构声明

    // 普通类
    class Student1(var name: String , var age: Int, var sex: Char) {

    复制代码
      // 注意事项:component0 顺序必须是 component1 component2 component3 和成员一一对应,顺序下来的
      operator fun component1() = name
      operator fun component2() = age
      operator fun component3() = sex

    }

    // 数据类
    data class Student2Data(var name: String , var age: Int, var sex: Char)

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

    复制代码
      val(name1, age1, sex1) = Student2Data("李四", 89, '男')
      println("数据类 结构后:name:$name1, age:$age1, sex:$sex1")
    
      val(_, age2, _) = Student1("李四", 89, '男')
      println("数据类 结构后: age2:$age2")

    }

  • 运算符重载

    // 写一个数据类,就是为了,toString 打印方便而已哦
    data class AddClass2(var number1: Int, var number2: Int) {
    operator fun plus(p1: AddClass2) : Int {
    return (number1 + p1.number1) + (number2 + p1.number2)
    }
    }

    // TODO 94-Kotlin语言的运算符重载学习
    fun main() {
    // C++语言 +运算符重载就行了 -运算符重载就行了
    // KT语言 plus代表+运算符重载

    复制代码
      println(AddClass2(1, 1) + AddClass2(2, 2))

    }

  • 密封类
    ‌1. 替代枚举(Enum),但支持更灵活的数据类型‌
    ‌枚举的局限性‌:每个枚举值只能是单例,不能携带不同的数据。
    ‌密封类的优势‌:每个子类可以有自己的属性和方法,且可以是object(单例)或data class(带数据)。

    sealed class PaymentMethod {
    data class CreditCard(val cardNumber: String, val expiryDate: String) : PaymentMethod()
    data class PayPal(val email: String) : PaymentMethod()
    object Cash : PaymentMethod()
    }

‌2. 结合 when 表达式,实现编译期安全检查‌

复制代码
sealed class ApiResult {
    data class Success(val data: String) : ApiResult()
    data class Error(val message: String, val code: Int) : ApiResult()
}

fun handleResult(result: ApiResult) = when (result) {
    is ApiResult.Success -> println("成功: ${result.data}")
    is ApiResult.Error -> println("错误: ${result.message} (${result.code})")
    // 不需要 else,编译器确保所有情况已覆盖
}
  1. 适用于状态管理(如 UI 状态、业务逻辑状态)‌

    sealed class UiState {
    object Loading : UiState()
    data class Success(val data: List<String>) : UiState()
    data class Error(val message: String) : UiState()
    }

    fun updateUI(state: UiState) = when (state) {
    is UiState.Loading -> showProgressBar()
    is UiState.Success -> showData(state.data)
    is UiState.Error -> showError(state.message)
    }

‌4. 替代 when + else 的防御性编程‌

相关推荐
AD钙奶-lalala1 小时前
android:foregroundServiceType详解
android
@老蝴2 小时前
C语言 — 通讯录模拟实现
c语言·开发语言·算法
♚卜卦4 小时前
面向对象 设计模式简述(1.创建型模式)
开发语言·设计模式
安全系统学习4 小时前
网络安全之RCE简单分析
开发语言·python·算法·安全·web安全
大胃粥4 小时前
Android V app 冷启动(13) 焦点窗口更新
android
Swift社区4 小时前
Swift 解法详解:如何在二叉树中寻找最长连续序列
开发语言·ios·swift
yutian06065 小时前
C# 支持 ToolTip 功能的控件,鼠标悬停弹提示框
开发语言·microsoft·c#
byte轻骑兵5 小时前
【C++特殊工具与技术】优化内存分配(四):定位new表达式、类特定的new、delete表达式
开发语言·c++
chao_7895 小时前
标注工具核心代码解析——class AnnotationVie【canvas.py]
开发语言·python·qt5
YuTaoShao5 小时前
Java八股文——JVM「内存模型篇」
java·开发语言·jvm