Kotlin学习笔记-扩展

443 阅读3分钟

kotlin 扩展

Kotlin 能够扩展一个类的新功能而无需继承该类或者使用像装饰者这样的设计模式。 这通过叫做 扩展 的特殊声明完成。 例如,你可以为一个你不能修改的、来自第三方库中的类编写一个新的函数。 这个新增的函数就像那个原始类本来就有的函数一样,可以用普通的方法调用。 这种机制称为 扩展函数 。此外,也有 扩展属性 , 允许你为一个已经存在的类添加新的属性。

使用小结:扩展可以很好地解决java中充斥的各种辅助类问题。

本文主要列出自己的学习总结,具体介绍请参考kotlin官方文档中文翻译站

1. 扩展本身并不会真正修改目标类,也就是说它不会在目标类中插入新的属性或是方法

扩展函数不过就是自动生成一个带有当前对象的函数,当我们在 Kotlin 中调用扩展函数时,编译器将会调用自动生成的函数并且传入当前的对象。

2.扩展函数的解析是静态分发的,而不是动态的,即不支持多态,调用只取决于对象的声明类型

这句话的意思大致是:调用是由对象声明类型所决定的,而不是由对象的实际类型决定。 例:

open class A

class B: A()

fun A.a() = "a"
fun B.a() = "b"

fun print(a: A){
    println(a.a())
}

fun main(args: array<String>){
    print(A())
    print(B())
}

打印结果:

a
a

3.扩展函数可以和既有函数重名,但是调用时,既有函数优先级较高

意思很明确,扩展类的原函数可以和扩展函数同名,但是调用同名函数时,真正被调用的原函数。 例:

open class A{
    a(){
        println("A的方法a")
    }
}

fun A.a(){
     println("A的扩展方法a")
}

fun print(){
    println(A().a())
}

fun main(args: array<String>){
    print()
}

打印结果:

A的方法a

4.扩展函数可重载既有函数

在第三点的基础上,我们可以扩展同名函数,但是是以重载的方式实现,这样调用同名方法时便互补影响。 例:

open class A{
    a(){
        println("A的方法a")
    }
}

fun A.a(c: Int){
     println("A的扩展方法a")
}

fun print(){
    println(A().a(1))
}

fun main(args: array<String>){
    print()
}

打印结果:

A的扩展方法a

5.可空类型也可以增加扩展函数

例:

fun Any?.toString (): String {
	if(null == this){
		returnnull”
	}
	return toString()
}

说明:

该扩展方法处理的对象是一个可空的任意类型(Any是kotlin中的根类型),这种扩展是允许的,且当前例子是为了解决通用可空对象调用toString()方法的处理。

6.伴生对象也可以扩展

例:

class MyClass {
    companion object { }  // 将被称为 "Companion"
}

fun MyClass.Companion.printCompanion() { println("companion") }

fun main() {
    MyClass.printCompanion()
}

说明:

伴生对象的扩展和普通类差不多,只是它是依附于和它相伴的class去调用。伴生对象的扩展方法的用途暂时没有想到,也许可以用于页面跳转startActivity时的通用处理?

7.扩展的作用域

扩展函数可以定义为top level function(常用),作用域是包层面。也可以定义在类当中,且定义在类当中时可以是当前类的扩展函数也可以是其他类的扩展函数,这里的扩展函数作用域也就是当前类,一般不愿意对外暴露的扩展函数可以这么使用。

注:

本类中生成其他类的扩展函数时,可调用本类中的方法。另外本类的方法名可与他类在本类生成的扩展函数名称相同,当以上两个名字出现冲突时,扩展接收者的优先级最高。

8.扩展属性

扩展属性比较简单,与扩展函数使用方法基本一致,在此不做赘述。