【Kotlin】扩展接收者 与 分发接收者 ( 类内部扩展用法 | 注意事项 | open 修饰扩展 )

简介: 【Kotlin】扩展接收者 与 分发接收者 ( 类内部扩展用法 | 注意事项 | open 修饰扩展 )

文章目录

I . 类内部扩展其它类

II . 扩展接收者 与 分发接收者 注意事项

III . open 修饰 分发接收者 类型中的扩展



I . 类内部扩展其它类


1 . 扩展函数 / 属性声明的位置 : 之前的扩展都是在类的外部 , Kotlin 文件中定义的 , 在 类内部 也可以定义 其它类 的扩展函数 与 扩展属性 ;



2 . 类内部定扩展 : 在这样的扩展函数或扩展属性访问器中 , 可以直接调用本类的成员 ; 类内部扩展其它类 , 也相应产生了两个概念 , 扩展接收者 和 分发接收者 ;



① 扩展接收者 : 被扩展的接收者类型的类对象实例 , 叫做扩展接收者 ;


② 分发接收者 : 扩展函数/属性所在的实例 , 叫做分发接收者 ;



注意 : 扩展接收者 和 分发接收者 都是类的 对象实例 ;



③ 分发接收者中的扩展 : 扩展中可以访问 分发接收者 和 扩展接收者 , 两个实例对象的成员 ;



3 . 扩展接收者 和 分发接收者 代码示例 :


//扩展接收者类型 , 为该类扩展函数
class Teacher{
    var name : String = "Jerry"
}
//分发接收者类型 , 在该类中为 Teacher 扩展函数
class Student{
    var name : String = "Tom"
    // Student 类中的方法
    fun study(){
        println("${name} 在学习")
    }
    /*
        在 Student 类中为 Teacher 类定义扩展函数
        扩展函数内部可以调用 Teacher 和 Student 两个对象的成员
     */
    fun Teacher.teach(){
        //调用 扩展接收者 的 name 属性
        println("${this.name} 在讲课")
        //调用 分发接收者 的 name 属性
        println("${this@Student.name} 在听课")
    }
    //类内部扩展的函数 , 只能在 分发接收者 对象中调用 , 不能在类外部调用
    fun teachAndStudy(){
        Teacher().teach()
    }
}
fun main() {
    Student().teachAndStudy()
    //在分发接收者类型中定义的扩展 ,
    // 只能在该类内部调用 , 在类外部是访问不到的
    //Teacher().teach()
}


执行结果 :


Jerry 在讲课
Tom 在听课


II . 扩展接收者 与 分发接收者 注意事项


1 . 扩展函数 / 属性 中可以调用 扩展接收者 与 分发接收者 两个对象的成员 : 如上面的 Teach.teach 扩展函数中 , 即可以调用 Teacher ( 扩展接收者 ) 对象的 name 属性 , 也可以调用 Student ( 分发接收者 ) 对象的 name 属性 ;



2 . 扩展接收者 与 分发接收者 的 同名 属性 / 函数 优先级 : 如上面的示例中 , 在扩展中同时调用 二者 的 name 属性 , 默认调用的是扩展接收者 ( 被扩展类对象 ) 的 name 属性 , 如果调用 分发接收者 ( 本类 Student ) 的 name 属性 , 需要使用 this@Student.name 调用 ;

image.png




3 . 扩展作用域 : 在分发接收者类型中定义的扩展 , 只能在该类内部调用 , 在类外部是访问不到的 ; 在上面的示例中注释掉了该行代码 ;


image.png




III . open 修饰 分发接收者 类型中的扩展


情形描述 : 在分发接收者类型中 , 可以使用 open 关键字修饰扩展 , 这个扩展函数 , 可以在子类中重写覆盖 ;



① 代码示例 : Student 使用 open 修饰 , fun Teacher.teach 扩展函数也使用 open 修饰 ; 在子类中可以重写 fun Teacher.teach 扩展函数 ;



//扩展接收者类型 , 为该类扩展函数
class Teacher{
    var name : String = "Jerry"
}
//分发接收者类型 , 在该类中为 Teacher 扩展函数
//  注意将 Student 类也声明成 open 类 , 才能被继承
open class Student{
    var name : String = "Tom"
    // Student 类中的方法
    fun study(){
        println("${name} 在学习")
    }
    /*
        在 Student 类中为 Teacher 类定义扩展函数
        扩展函数内部可以调用 Teacher 和 Student 两个对象的成员
     */
    open fun Teacher.teach(){
        //调用 扩展接收者 的 name 属性
        println("${this.name} 在讲课")
        //调用 分发接收者 的 name 属性
        println("${this@Student.name} 在听课")
    }
    //类内部扩展的函数 , 只能在 分发接收者 对象中调用 , 不能在类外部调用
    fun teachAndStudy(){
        Teacher().teach()
    }
}
//Student 子类 , 其中重写了扩展
class MaleStudent : Student(){
    override fun Teacher.teach() {
        //调用 扩展接收者 的 name 属性
        println("${this.name} 在讲课")
        //调用 分发接收者 的 name 属性
        println("男学生 ${this@MaleStudent.name} 在听课")
    }
}
fun main() {
    Student().teachAndStudy()
    //子类中调用了子类重写的扩展函数
    MaleStudent().teachAndStudy()
    //在分发接收者类型中定义的扩展 ,
    // 只能在该类内部调用 , 在类外部是访问不到的
    //Teacher().teach()
}


② 执行结果 :


Jerry 在讲课
Tom 在听课
Jerry 在讲课
男学生 Tom 在听课


目录
相关文章
|
8月前
|
分布式计算 Java 数据安全/隐私保护
Kotlin 学习笔记(二)—— 数据类、枚举类、循环、常用集合及操作符的写法(下 )
Kotlin 学习笔记(二)—— 数据类、枚举类、循环、常用集合及操作符的写法(下)
45 0
|
3天前
|
Kotlin
Kotlin类的定义、构造函数、封装、继承和多态
Kotlin类的定义、构造函数、封装、继承和多态
7 1
|
3天前
|
存储 Java Kotlin
Kotlin中的嵌套类、内部类、枚举类、密封类、数据类、单例类、伴生对象
Kotlin中的嵌套类、内部类、枚举类、密封类、数据类、单例类、伴生对象
7 1
|
17天前
|
安全 Android开发 Kotlin
Android面试题之Kotlin的几种常见的类
这篇文章探讨了Kotlin编程语言中的初始化顺序、延迟初始化、惰性初始化、`lateinit`与`by lazy`的区别、初始化注意事项、继承、嵌套类、数据类、单例类和枚举类的使用,以及密封类的概念。文中通过示例代码详细解释了各种特性,并提醒读者关注初始化顺序和线程安全问题。同时,鼓励读者关注作者的公众号“AntDream”获取更多相关文章。
19 1
|
10月前
|
API Kotlin
Kotlin中扩展函数、infix关键字、apply函数和DSL的详解
Kotlin中扩展函数、infix关键字、apply函数和DSL的详解
89 0
|
10月前
|
Kotlin
Kotlin 中定义类、field关键字,主构造函数和次构造函数详解
Kotlin 中定义类、field关键字,主构造函数和次构造函数详解
111 0
|
8月前
|
存储 Java 编译器
Kotlin 学习笔记(四)—— 作用域函数、inline 关键字、反引号等 Kotlin 基本用法(下)
Kotlin 学习笔记(四)—— 作用域函数、inline 关键字、反引号等 Kotlin 基本用法(下)
38 0
|
8月前
|
Java Android开发 开发者
Kotlin 学习笔记(四)—— 作用域函数、inline 关键字、反引号等 Kotlin 基本用法(上)
Kotlin 学习笔记(四)—— 作用域函数、inline 关键字、反引号等 Kotlin 基本用法(上)
66 0
|
8月前
|
Java Kotlin
Kotlin 学习笔记(二)—— 数据类、枚举类、循环、常用集合及操作符的写法(上)
Kotlin 学习笔记(二)—— 数据类、枚举类、循环、常用集合及操作符的写法(上)
37 0
|
10月前
|
安全 Java 编译器
Kotlin 学习笔记(一)—— 基本类型、函数、lambda、类与对象的写法
Kotlin 作为 Android 开发的首选语言,其基础语法和特性需要重点学习。本文概括总结了 Kotlin 的基本类型、关键字、函数、闭包、高阶函数、类与对象等核心知识点,并给出示例代码进行讲解。
160 0
Kotlin 学习笔记(一)—— 基本类型、函数、lambda、类与对象的写法