先定义一个类:
package com.init.demo.extend class Say{ fun sayHi() = println("Hi") fun sayBye() = println("Bye") }
测试类:
package com.init.demo.extend fun main(args: Array<String>) { val say = Say() say.sayGreat() 2.sayPlay() val mmo = mutableMapOf<String, Int?>() mmo.addNotNull("one",2) mmo.addNotNull("two",null) mmo.addNotNull("three",3) println(mmo) } /** * 类的方法和属性都可以扩展 * 扩展类Say的方法和属性 * 不一定是在内部扩展,也可以在其它类中扩展 * eg:如下 */ fun Say.sayGreat() = println("Great!") fun Say.sayLove() = println("Love!") fun Say.sayHah() = println("Hah!") fun Say.sayPlay() = println("Play!") fun Int.sayPlay() = println("Play!") /** * 扩展不能真正地修改它们所扩展的类。 * 通过定义一个扩展,你并没有在一个类中插入新成员, * 仅仅可以通过该类型的变量用点表达式去调用这个新函数。 * 所扩展的函数并不是将它们变成该类的方法,而是同一种特殊的方式定义一个函数, * 可以通过“实例名.该实例所属类的扩展函数(参数)”来执行它们。 * 并且扩展函数是静态解析的。这意味着调用的扩展函数是由函数调用所在的表达式的类型决定的, * 而不是由表达式运行时求值结果决定的。这和Java的多态机制是完全相反的。 */ fun MutableMap<String,Int?>.addNotNull(key:String,value:Int?){ if(value !=null){ this[key] = value } }
实例类举证1:
package com.init.demo.extend class DemoExtendPerson { var name: String = "" var age: Int = 0 fun printInfomation() = println("name:$name") } //fun DemoExtendPerson.printInfomation() = println("age:${this.age}") fun DemoExtendPerson.printInfomation(count:Int) { for (i in 1..count){ println("age:${this.age}") } }
实例类举证测试1:
package com.init.demo.extend fun main(args: Array<String>) { val demoExtendPerson = DemoExtendPerson() demoExtendPerson.age = 20 demoExtendPerson.name = "小明" demoExtendPerson.printInfomation() // 输出:name:小明 /** * 修改了扩展方法以后 eg * Kotlin 会根据不同的参数选择不同的扩展函数 * 入股没有参数 就会选择类内部的函数 * 扩展函数在和内部函数的命名、参数数量和参数类型相同时, * 编译器无法区分,会优先选择类内部的函数 */ demoExtendPerson.printInfomation(3) // 输出: /*age:20 age:20 age:20*/ }
实例类举证2:
package com.init.demo.extend class DemoExtendPerson1{ /** * 对属性的扩展也是有局限性的,因为我们扩展属性并不是在类的内部将这个属性插入, * 所以不能有初始化器,它们的行为只能由显式提供的ge阳r和se忧er定义。 * 也就是说,我们不能用构造器对这个属性进行初始化,也不能有初始化器。 * v a r / v al类名.属性名 */ var name: String = "" var _age: Int = 0 } fun DemoExtendPerson1?.printInfomation() { if(this==null){ println("Sorry,this is null") }else{ println("name:$name,age:$age") } } /** * 如果不初始化,会报error * Extension property must have accessors or be abstract 意思是:属性必须初始化 * 如果不写setter或者getter,会报error * Extension property must have accessors or be abstract 意思是:属性必须初始化 * 调用了初始化器,初始化器会通过属性的幕后字段为其赋初值, * 而扩展属性根本就没有幕后字段,因为它根本就不是这个类内部定义的成员。 * 幕后字段field:unresolved reference: field * 扩展属性没有幕后字段 * 对扩展属性赋值的时候,其实是对中间变量进行赋值, * 如果想对扩展属性取值,骑士也是对中间变量进行取值 */ var DemoExtendPerson1.age: Int get() = this._age set(value) { // field = value this._age = value }
实例类举证测试2:
package com.init.demo.extend fun main(args: Array<String>) { val person:DemoExtendPerson1? = null println(person.printInfomation()) val demoExtendPerson1:DemoExtendPerson1? = DemoExtendPerson1() demoExtendPerson1?.name = "SHEN" /** * 把一些重复的代码封装到扩展属性的访问中,有利于维护代码 */ demoExtendPerson1?.age = 12 demoExtendPerson1?.printInfomation() //最后输出:name:SHEN,age:12 }
对于扩展函数:只能访问类声明下的函数:
package com.init.demo.extend open class DemoExtendA{ open fun printHello() = println("Hello,A") } class DemoExtendB:DemoExtendA(){ override fun printHello() = println("Hello,B") } fun DemoExtendA.printA() = println("Hello,A") fun DemoExtendB.printB() = println("Hello,B") /** * 对于扩展函数:只能访问类声明下的函数 */ fun main(args: Array<String>) { val ele:DemoExtendA = DemoExtendB() ele.printA() /** * ele 不能访问printB方法,因为类声明下的函数没有printB函数 * 如果要访问,会报error: * //Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: * public fun DemoExtendB.printB(): Unit defined in com.init.demo.extend in file DemoExtendA. */ // ele.printB() /** * 类中的方法时动态解析的,声明方法是静态解析的 */ ele.printHello() val ele1 = DemoExtendB() ele1.printB() }
最后,
package com.init.demo.extend class Fruits(names: List<String>) { val names: List<String> = names fun printInfomation() = names.forEach { print("\t${it}") } } class Box(size: Int) { val size: Int = size fun Fruits.printALl() { this@Box.printInfomation() } fun haveFruits(f: Fruits) { // println("I am a box,size is $size") // println("I have fruits:") printInfomation() f.printALl() } fun printInfomation() { println("I am a box,size is $size") println("I have fruits:") } } fun main(args: Array<String>) { val fruits = Fruits(listOf("Banana", "Apple", "Watermelon")) val box = Box(15) /** *修改haveFruits和添加Box内部方法printInfomation前 的输出: * I am a box,size is 15 * I have fruits: * Banana Apple Watermelon * 修改haveFruits和添加Box内部方法printInfomation后 的输出 * I am a box,size is 15 * I have fruits: * I am a box,size is 15 * I have fruits: */ box.haveFruits(fruits) val list = mutableListOf<Int>(1, 2, 3) swapindexFromList(list, 0, 2) println("List对象两个圆度的位置交换:"+list) val list1= mutableListOf<Int>(1 , 2, 3) list1.swapindexFromList1 (0, 2) println("List对象两个圆度的位置交换方法扩展:"+list1) /*输出: List对象两个圆度的位置交换:[3, 2, 1] List对象两个圆度的位置交换方法扩展:[3, 2, 1]*/ } /** * List对象两个圆度的位置交换 */ fun swapindexFromList(list: MutableList<Int>, indexl: Int, index2: Int) { val temp = list[indexl] list[indexl] = list[index2] list[index2] = temp } /** * List对象两个圆度的位置交换方法扩展 */ fun MutableList<Int>.swapindexFromList1(indexl: Int, index2: Int) { val temp = this[indexl] this[indexl] = this[index2] this[index2] = temp }