【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 的是一个子类对象,也是调用父类的扩展方法,这跟多态是不一样的。当扩展方法在贬义词出现歧义时,只会根据形参类型选择扩展函数

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

相关推荐
androidwork17 小时前
使用 Kotlin 和 Jetpack Compose 开发 Wear OS 应用的完整指南
android·kotlin
_龙小鱼_17 小时前
Kotlin变量与数据类型详解
开发语言·微信·kotlin
androidwork1 天前
掌握 Kotlin Android 单元测试:MockK 框架深度实践指南
android·kotlin
圈圈编码1 天前
MVVM框架
android·学习·kotlin
橙子199110162 天前
在 Kotlin 中,什么是解构,如何使用?
android·开发语言·kotlin
androidwork2 天前
Android 中使用通知(Kotlin 版)
android·kotlin
_龙小鱼_2 天前
卡顿检测与 Choreographer 原理
android·kotlin
androidwork2 天前
Kotlin Android单元测试MockK指南
android·kotlin
麻辣璐璐2 天前
Kotlin并发请求的一些知识记录
android·kotlin
androidwork3 天前
Arrow库:函数式编程在Kotlin Android中的深度实践
android·java·kotlin