opoojkk

Kotlin的fun interface

xx
目次

当我们写Java时有这么一种情况,需要用到回调,但是回调中只有一个方法, 这时候的写法可以更简便,举个例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public class SAMJava {
    public static void main(String[] args) {
        // 写法1
        execute(new BlockJava() {
            @Override
            public void invoke() {
               // do something
            }
        });
    }

    static void execute(BlockJava blockJava) {
        blockJava.invoke();
    }
}

interface BlockJava {
    void invoke();
}

上面是Java中传递匿名对象最最普通的写法,换用lambda的形式可以写成:

1
2
3
4
// 写法2
execute(() -> {
    // do something
});

看起来干净了很多,这就是SAM(Single Abstract Method)。要说有什么作用,就是让代码看起来很干净。这也是有限制的,只能是接口类中有一个方法需要实现的时候,当接口的中有两个方法就不行了,只能老老实实用的用方法1.

这都是在Java中,Kotlin中有些不同。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
object SAMKt {
    @JvmStatic
    fun main(args: Array<String>) {
        // 写法1
        execute(object : BlockKotlin {
            override fun invoke() {
                // do something
            }
        })
    }

    fun execute(blockJava: BlockKotlin) {
        blockJava.invoke()
    }
}

interface BlockKotlin {
    fun invoke() //    void fiinish();
}

匿名对象的形式当然是可以的,如果想换成Kotlin中lamdbas的写法,代码检查就是提示错误。

1
2
3
4
// 写法2,报错
execute {
    // do something
}

Kotlin中能不能呢,能。但有点不同,你需要声明接口是fun interface:

1
2
3
fun interface BlockKotlin {
    fun invoke() //    void fiinish();
}

这时候还会提示你可以写成了写法2。
除此之外,还有一种写法。我们知道Kotlin是有高阶函数的,高阶函数可以做这事。

1
2
3
4
5
6
fun execute2(block: () -> Unit) {
    block()
}


execute2 {  }

这样也是没问题的。

参考 #

标签:
Categories: