Kotlin扩展函数和属性

 在Kotlin中,为什么会有扩展?因为可以让使用者(或定义者)不修改即有源代码的情况下,同时又不借助于装饰模式等任何一种设计模式的情况下, 以一种比较快捷和方便的方式去为一个即有的类增加功能,而提供的这样的一种手段。Kotlin通过扩展可以很好的解决Java中充斥的各种辅助类问题。

  1. 扩展函数(方法)
    如下所示,是一个扩展函数的例子:
/**
 * 扩展性,extension
 * 在不改变原有类结构的情况下,给这个类动态的增加一些额外的功能
 */
class ExtensionTest {
    fun add(a: Int, b: Int) = a + b

    fun sub(a: Int, b: Int) = a - b
}

/**
 * ExtensionTest类的扩展方法
 */
fun ExtensionTest.mul(a: Int, b: Int) = a * b

fun main(args: Array) {
    var extensionTest = ExtensionTest();

    println(extensionTest.add(1, 3))
    println(extensionTest.sub(2, 2))
    println(extensionTest.mul(3, 1))
}

输出结果:
4
0
3
  • 扩展本身并不会真正的修改目标类,也就是说它并不会在目录类中插入新的属性或方法;
  • 扩展函数的解析是静态分发的,而不是动态的,即不支持多态,调用只取决于对象的声明类型;
  • 调用是由对象的声明类型所决定的,而不是由对象的实际类型决定。
    如下所示:
open class ClassA

class ClassB: ClassA()

fun ClassA.a() = "a"

fun ClassB.a() = "b"

fun myPrint(a: ClassA) {
    println(a.a())
}

fun main(args: Array) {
    myPrint(ClassA())
}

输出结果:
a

// 由ClassA改为ClassB,输出结果也是a
fun main(args: Array) {
    myPrint(ClassB())
}

输出结果:
a

如果一个类有了某一个方法,然后对这个类进行扩展,扩展的方法名及签名都完全一样,类里面即有的方法优先级最高。注:不过实际情况不会出现,不会对类扩展一个跟类里包含的方法一样的方法。如下所示:

class ClassC {
    fun foo() {
        println("cc.foo")
    }
}

fun ClassC.foo() {
    println("cc.foo2")
}

fun main(args: Array) {
    ClassC().foo()
}

输出结果:
cc.foo
  1. 扩展属性
    如下所示,是一个扩展属性的例子:
class ExtensionProperty

val ExtensionProperty.name: String
    get() = "hello"

fun main(args: Array) {
    var extensionProperty = ExtensionProperty()
    println(extensionProperty.name)
}

输出结果:
hello
  1. 伴生对象扩展
    如下所示,是一个伴生对象扩展的例子:
class CompanionExtension {

    companion object MyObject {

    }
}

fun CompanionExtension.MyObject.method() {
    println("hello world!")
}

fun main(args: Array) {
    CompanionExtension.method()
}

输出结果:
hello world!
  1. 扩展的作用域
  • 扩展函数所定义在的类实例叫做分发接收者(dispatch receiver);
  • 扩展函数所扩展的那个类的实例叫做扩展接收者(extension receiver);
  • 当以上两个名字出现冲突时,扩展接收者的优先级最高。
    如下所示:
class Demo {
    fun method() {
        println("demo method")
    }
}

class Demo2() {
    fun method2() {

    }

    fun Demo.hello() {
        method()
        method2()
    }

    fun world(demo: Demo) {
        demo.hello()
    }

    fun Demo.output() {
        println(toString())
        println(this@Demo2.toString())
    }

    fun test() {
        var demo = Demo()
        demo.output()
    }
}

fun main(args: Array) {
    Demo2().test()
}

输出结果:
com.ssy.kotlin.demo.Demo@6e0be858
com.ssy.kotlin.demo.Demo2@61bbe9ba

注:this@Demo2,Kotlin提供的特殊语法,是为了解决函数(方法)重名的问题,this@分发接收者的名字。

你可能感兴趣的:(Kotlin扩展函数和属性)