【Kotlin 三】封装/继承/多态 属性覆盖 类的扩展

1.封装/继承/多态

1.1 封装

一般,我们将类的属性都声明为private,在类中通过暴露一部分public的方法来供外部读写对象属性

kotlin 复制代码
class Student (private var name: String) {
    fun getName(): String {
        return name
    }
    fun setName(name: String) {
        this.name = name
    }
}

1.2 继承

默认的Kotlin类是终态(不可继承)的,可以使用open标记可以被继承的类

1.2.1 初始化顺序

存在继承关系时,初始化一个子类对象的顺序为:

父类初始化 > 子类主构造函数 > 子类次要构造函数

1.2.2 属性覆盖

子类需要重写父类的某些函数时,可以如下操作:

  1. 父类/父类方法 使用open修饰
  2. 子类使用override关键字修饰要重写的方法
kotlin 复制代码
open class Student {
    open fun hello() = println("我会打招呼")
}

class ArtStudent : Student() {
    override fun hello() = println("哦哈哟")
}

可以使用is关键字判断某个对象是否是某个类的实现,类似于Java中的instance of

明确来了某个对象是哪个类以后,可以使用as关键字来强转

如果一个对象是可空类型(如Student?),可以使用as?进行强转,当对象为空时会直接返回一个null作为强转后的结果

2.类的扩展

常用的类扩展可以通过继承实现:子类可以在父类的基础上,通过定义更多的属性和方法来扩展父类的功能

Kotlin支持在类代码不对外开放/不能被继承的情况下,扩展类的功能,比如一些第三方类不向我们开放编辑权限,再或者本身就是Kotlin的一些基础类型(String)。这些类在Java语言中完全不能扩展,但是在Kotlin中可以

kotlin 复制代码
fun main() {
    val text = "1"
    text.test()
}

fun String.test() = "111"

类的扩展是静态的(相对于多态是动态来说的),比如下面这个例子

kotlin 复制代码
open class Father
class Son : Father()

fun Father.test() = "111"
fun Son.test() = "222"

fun printObject(s: Father) {
    println(s.test())
}

fun main() {
    printObject(Son())
}

// 打印结果:111

因为是静态扩展,所以即使传入 printObject 的是一个子类对象,也是调用父类的扩展方法,这跟多态是不一样的。当扩展方法在贬义词出现歧义时,只会根据形参类型选择扩展函数

如果类中已经定义了一个函数,然后静态扩展了一个同名同形参函数,扩展函数会失效(类中原本定义的函数优先级更高)

相关推荐
闲暇部落5 小时前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
长亭外的少年20 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
JIAY_WX20 小时前
kotlin
开发语言·kotlin
麦田里的守望者江1 天前
KMP 中的 expect 和 actual 声明
android·ios·kotlin
菠菠萝宝1 天前
【YOLOv8】安卓端部署-1-项目介绍
android·java·c++·yolo·目标检测·目标跟踪·kotlin
恋猫de小郭1 天前
Kotlin Multiplatform 未来将采用基于 JetBrains Fleet 定制的独立 IDE
开发语言·ide·kotlin
枫__________2 天前
kotlin 协程 job的cancel与cancelAndJoin区别
android·开发语言·kotlin
鸠摩智首席音效师2 天前
如何在 Ubuntu 上配置 Kotlin 应用环境 ?
linux·ubuntu·kotlin
jikuaidi6yuan4 天前
Java与Kotlin在鸿蒙中的地位
java·kotlin·harmonyos
liulanba4 天前
Kotlin的data class
前端·微信·kotlin