【Kotlin】Kotlin 类的继承 二 ( 属性覆盖 | 属性覆盖的四种情况 | 常量 / 变量 属性覆盖 | 子类初始化与属性覆盖 )

简介: 【Kotlin】Kotlin 类的继承 二 ( 属性覆盖 | 属性覆盖的四种情况 | 常量 / 变量 属性覆盖 | 子类初始化与属性覆盖 )

文章目录

I . 属性覆盖基本方式

II . 属性覆盖的四种情况

III . 常量 ( val ) / 变量 ( var ) 属性覆盖

IV . 子类初始化时考虑覆盖属性的使用



I . 属性覆盖基本方式


1 . 属性覆盖 : 属性覆盖与方法覆盖的方式基本相同 ;



① 属性覆盖前提 : 在父类中使用 open 修饰的属性 , 可以在子类中被覆盖 ;


② 属性覆盖方式 : 在子类中使用 override 修饰被覆盖的属性 ;



2 . 属性覆盖示例 :


open class Father {
    //被覆盖的属性需要使用 open 修饰
    open var age : Int = 60
}
class Son : Father() {
    //子类覆盖的属性需要使用 override 修饰
    override var age : Int = 28
}




II . 属性覆盖的四种情况


1 . 子类的覆盖属性的要求 : 子类中覆盖的属性有特定的要求 , 不能是延迟加载属性 , 下面列举几种常见的方式 ;



2 . 覆盖属性初始化 : 子类中使用 override 覆盖的属性需要设定一个初始值 ;


open class Father {
    open var age : Int = 60
}
class Son : Father() {
    override var age : Int = 18
}


3 . 覆盖属性设置 getter / setter 方法 : 子类中使用 override 覆盖的属性设置对应的 getter 和 setter 方法 ;


open class Father {
    open var age : Int = 60
}
class Son : Father() {
    override var age : Int
        get() {
            TODO()
        }
        set(value) {}
}



4 . 将子类和覆盖属性声明成抽象化的 : 子类可以声明成抽象类 , 其 override 属性也可以声明成抽象属性 ;


open class Father {
    open var age : Int = 60
}
abstract class Son : Father() {
    abstract override var age : Int
}



5 . 覆盖属性声明在子类主构造函数中 : 可以将子类中覆盖的父类属性声明在主构造函数中 , 如下示例 :


open class Father {
    open var age : Int = 60
}
class Son(override var age: Int) : Father() {
}



III . 常量 ( val ) / 变量 ( var ) 属性覆盖


1 . 常量覆盖 : 父类中 val 修饰的常量属性可以在子类中使用 val 或 var 覆盖 ;


open class Father {
    open val name : String = "Tom"
    open val age : Int = 60
}
class Son : Father() {
    //1 . 父类常量常规情况下被子类重写成常量
    override val name : String = "Jerry"
    //2 . 父类常量可以被子类重写成变量
    override var age : Int = 18
}



2 . 变量覆盖 : 父类中的 var 属性可以被子类中的 var 属性覆盖 , 不能被 val 属性覆盖 ;



① 代码示例 ( 正确 ) :


open class Father {
    open var age : Int = 60
}
class Son : Father() {
    //父类变量 只能 被子类重写成变量 , 不能被重写成常量
    override var age : Int = 18
}



② 错误示例 ( 错误 ) :




3 . 覆盖原理 :



① 常量覆盖 : 常量属性只有 get 方法 , 没有 set 方法 ; 子类将常量 override 成变量 , 就是为其多写了一个 set 方法 ;


② 变量覆盖 : 但是子类不能讲一个变量重写成常量 , 父类的方法可以修改添加 , 但是不能删除 ;




IV . 子类初始化时考虑覆盖属性的使用


1 . 子类初始化 : 子类初始化时 , 要先将父类进行初始化 , 然后开始初始化子类 ;



2 . 父类初始化流程 :



① 父类构造函数 : 先调用主构造函数 / 次构造函数 ;


② 父类初始化 : 然后调用父类属性构造器 和 init 初始化代码块 , 这两个模块优先级相同 , 根据其代码顺序从上到下执行 ;



3 . 子类初始化流程 : 执行完父类初始化后 , 开始执行子类初始化 ;



① 子类构造函数 : 执行子类构造函数剩余部分 ( 如果有的话 , 一般是次构造函数 ) ;


② 子类初始化 : 执行子类属性构造器 和 init 初始化代码块 代码 , 这两个模块优先级相同 , 根据其代码顺序从上到下执行 ;



4 . 初始化过程中的覆盖属性 : 这里加入对覆盖属性的考虑 , 父类初始化过程中 , 子类覆盖的属性还没有初始化 , 父类的 open 属性可能在子类初始化过程中被修改 ;



5 . 最佳实践 : 在父类中 , 尽量不在 构造函数 , init 初始化代码块 , 属性初始化 时使用被 open 关键字修饰的可覆盖属性成员 , 因为该值不稳定 , 会增加不确定因素 ;


目录
相关文章
|
9月前
|
Kotlin
Kotlin教程笔记(20) - 枚举与密封类
Kotlin教程笔记(20) - 枚举与密封类
91 8
|
9月前
|
Java Kotlin
Kotlin教程笔记(13) - 类及成员的可见性
Kotlin教程笔记(13) - 类及成员的可见性
110 3
|
9月前
|
存储 前端开发 Java
Kotlin教程笔记(18) - 数据类
Kotlin教程笔记(18) - 数据类
|
10月前
|
数据安全/隐私保护 Kotlin
Kotlin教程笔记(7) - 类成员
Kotlin教程笔记(7) - 类成员
|
Java
Kotlin的常量(val)和变量(var)的区别
一、首先看一个例子 二、val和var的分析 package net.println.kotlin.chapters /** * @author:wangdong * @description: */ /...
1273 0
|
3月前
|
安全 Java Android开发
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
140 0
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
|
11月前
|
JSON 调度 数据库
Android面试之5个Kotlin深度面试题:协程、密封类和高阶函数
本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点。文章详细解析了Kotlin中的协程、扩展函数、高阶函数、密封类及`inline`和`reified`关键字在Android开发中的应用,帮助读者更好地理解和使用这些特性。
211 1
|
12月前
|
Android开发 开发者 Kotlin
告别AsyncTask:一招教你用Kotlin协程重构Android应用,流畅度飙升的秘密武器
【9月更文挑战第13天】随着Android应用复杂度的增加,有效管理异步任务成为关键。Kotlin协程提供了一种优雅的并发操作处理方式,使异步编程更简单直观。本文通过具体示例介绍如何使用Kotlin协程优化Android应用性能,包括网络数据加载和UI更新。首先需在`build.gradle`中添加coroutines依赖。接着,通过定义挂起函数执行网络请求,并在`ViewModel`中使用`viewModelScope`启动协程,结合`Dispatchers.Main`更新UI,避免内存泄漏。使用协程不仅简化代码,还提升了程序健壮性。
407 1
|
安全 Android开发 Kotlin
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
**Kotlin中的`by lazy`和`lateinit`都是延迟初始化技术。`by lazy`用于只读属性,线程安全,首次访问时初始化;`lateinit`用于可变属性,需手动初始化,非线程安全。`by lazy`支持线程安全模式选择,而`lateinit`适用于构造函数后初始化。选择依赖于属性特性和使用场景。**
377 5
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
|
调度 Android开发 开发者
【颠覆传统!】Kotlin协程魔法:解锁Android应用极速体验,带你领略多线程优化的无限魅力!
【8月更文挑战第12天】多线程对现代Android应用至关重要,能显著提升性能与体验。本文探讨Kotlin中的高效多线程实践。首先,理解主线程(UI线程)的角色,避免阻塞它。Kotlin协程作为轻量级线程,简化异步编程。示例展示了如何使用`kotlinx.coroutines`库创建协程,执行后台任务而不影响UI。此外,通过协程与Retrofit结合,实现了网络数据的异步加载,并安全地更新UI。协程不仅提高代码可读性,还能确保程序高效运行,不阻塞主线程,是构建高性能Android应用的关键。
175 4