Kotlin扩展函数允许我们在不改变已有类的情况下,为类添加新的函数,该函数为静态函数,
例如:
open class Animal
class Dog : Animal()
fun Animal.name() = "animal"
fun Dog.name() = "dog"
fun Animal.printName(anim:Animal){
println(anim.name())
}
fun main(args:Array<String>){
Dog().printName(Dog())///打印 animal
}
java要调用扩展函数要将被扩展的对象传进去
假如在调用某一个函数,而该函数在分发接受者和扩展接受者均存在,则以扩展接收者优先,要引用分发接收者的成员你可以使用限定的 this 语法。
class D {
fun bar() { println("D bar") }
}
class C {
fun bar() { println("C bar") } // 与 D 类 的 bar 同名
fun D.foo() {
bar() // 调用 D.bar(),扩展接收者优先
this@C.bar() // 调用 C.bar()
}
fun caller(d: D) {
d.foo() // 调用扩展函数
}
}
fun main(args: Array<String>) {
val c: C = C()
val d: D = D()
c.caller(d)
}
D bar
C bar
(1)类内扩展的伴随对象函数和类外扩展的伴随对象可以同名,它们是两个独立的函数,互不影响;
(2)当类内扩展的伴随对象函数和类外扩展的伴随对象同名时,类内的其它函数优先引用类内扩展的伴随对象函数,即对于类内其它成员函数来说,类内扩展屏蔽类外扩展;
(3)类内扩展的伴随对象函数只能被类内的函数引用,不能被类外的函数和伴随对象内的函数引用;
(4)类外扩展的伴随对象函数可以被伴随对象内的函数引用,;
class MyClass {
companion object {
val myClassField1: Int = 1
var myClassField2 = "this is myClassField2"
fun companionFun1() {
println("this is 1st companion function.")
foo()//半生对象内有调用半生对象的,如下注释掉的代码,如果没有,调用外部扩展函数,如果也没有就会报错
}
fun companionFun2() {
println("this is 2st companion function.")
companionFun1()
}
// fun foo(){//会屏蔽掉外部的扩展函数
// }
}
/**生成的class文件 扩展的函数非静态
当类内扩展的伴随对象函数和类外扩展的伴随对象同名时,类内的其它函数优先引用类内扩展的伴随对象函数,即对于类内其它成员函数来说,类内扩展屏蔽类外扩展
public final void foo(@NotNull Companion $receiver)
{
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");String str = "伴随对象的扩展函数(内部)";System.out.println(str);
}*/
fun MyClass.Companion.foo() {
println("伴随对象的扩展函数(内部)")
}
/***生成的class文件 扩展的函数非静态
public final void foo(@NotNull MyClass $receiver)
{
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");String str = "foo 外部扩展函数(内部)";System.out.println(str);
}*/
fun MyClass.foo(){
println("foo 外部扩展函数(内部)")
}
fun test2() {
MyClass.foo() //调用 MyClass.Companion.foo() ,如果没有,调用外部伴生扩展函数
MyClass().foo()//调用 MyClass.foo(),如果没有,调用外部扩展函数
}
init {
test2()
}
}
/**生成的class文件
public static final int getNo(@NotNull MyClass.Companion $receiver)
{
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");return 10;
}*/
val MyClass.Companion.no: Int
get() = 10
/***生成的class文件
public static final void foo(@NotNull MyClass.Companion $receiver)
{
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");String str = "foo 伴随对象外部扩展函数";System.out.println(str);
}*/
fun MyClass.Companion.foo() {
println("foo 伴随对象外部扩展函数")
}
/***生成的class文件
public static final void foo(@NotNull MyClass $receiver)
{
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");String str = foo 外部扩展函数";System.out.println(str);
}*/
fun MyClass.foo(){
println("foo 外部扩展函数")
}
/**生成的class文件
public static final void main(@NotNull String[] args)
{
Intrinsics.checkParameterIsNotNull(args, "args");String str = "no:" + getNo(MyClass.Companion);System.out.println(str);
str = "field1:" + MyClass.Companion.getMyClassField1();System.out.println(str);
str = "field2:" + MyClass.Companion.getMyClassField2();System.out.println(str);
foo(MyClass.Companion);
MyClass.Companion.companionFun2();
new MyClass();
}*/
fun main(args: Array<String>) {
println("no:${MyClass.no}")
println("field1:${MyClass.myClassField1}")
println("field2:${MyClass.myClassField2}")
MyClass.foo()
MyClass.companionFun2()
MyClass().foo()
}
执行结果:
no:10
field1:1
field2:this is myClassField2
foo 伴随对象外部扩展函数
this is 2st companion function.
this is 1st companion function.
foo 伴随对象外部扩展函数
伴随对象的扩展函数(内部)
网友评论