【Kotlin】扩展接收者 与 分发接收者 ( 类内部扩展用法 | 注意事项 | 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()
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
执行结果 :
Jerry 在讲课
Tom 在听课
- 1
- 2
II . 扩展接收者 与 分发接收者 注意事项
1 . 扩展函数 / 属性 中可以调用 扩展接收者 与 分发接收者 两个对象的成员 : 如上面的 Teach.teach 扩展函数中 , 即可以调用 Teacher ( 扩展接收者 ) 对象的 name 属性 , 也可以调用 Student ( 分发接收者 ) 对象的 name 属性 ;
2 . 扩展接收者 与 分发接收者 的 同名 属性 / 函数 优先级 : 如上面的示例中 , 在扩展中同时调用 二者 的 name 属性 , 默认调用的是扩展接收者 ( 被扩展类对象 ) 的 name 属性 , 如果调用 分发接收者 ( 本类 Student ) 的 name 属性 , 需要使用 this@Student.name
调用 ;
3 . 扩展作用域 : 在分发接收者类型中定义的扩展 , 只能在该类内部调用 , 在类外部是访问不到的 ; 在上面的示例中注释掉了该行代码 ;
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()
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
② 执行结果 :
Jerry 在讲课
Tom 在听课
Jerry 在讲课
男学生 Tom 在听课
- 1
- 2
- 3
- 4
文章来源: hanshuliang.blog.csdn.net,作者:韩曙亮,版权归原作者所有,如需转载,请联系作者。
原文链接:hanshuliang.blog.csdn.net/article/details/105275000
- 点赞
- 收藏
- 关注作者
评论(0)