Kotlin的SAM转换
2021-02-23 本文已影响0人
CarlosLynn
Java中的SAM
Java8之后,我们将只有单一方法的接口称为SAM(Single Abstract Method)接口,Java8通过Lambda可以大大简化对于SAM接口的调用。
“SAM”代表“单一抽象方法”,“SAM类型”是指像Runnable,Callable等接口.Lambda表达式,Java 8中的一个新功能,被认为是SAM类型,可以自由转换为它们。
例如,使用这样的接口:
public interface Callable<T> {
T call();
}
可以使用lambda表达式声明Callable,如下所示:
public static void main(String[] args) {
Callable<String> strCallable = () -> "Hello world!";
System.out.println(strCallable.call());
// prints "Hello world!"
//System.out.println("System");
}
有引入Lambda之前,我们是这样调用Sam类型的接口
public interface IBuy {
void onBuy(double money);
}
public static void main(String[] args) {
buyBike(new IBuy() {
@Override
public void onBuy(double money) {
System.out.println("buyBike:" + money);
}
});
buyCar(new IBuy() {
@Override
public void onBuy(double money) {
System.out.println("buyCar:" + money);
}
});
}
public static void buyBike(IBuy buy) {
buy.onBuy(500.00);
}
public static void buyCar(IBuy buy) {
buy.onBuy(50000.00);
}
我们需要实现一个IBuy的匿名内部类对象,即使只有一个方法,也要规规矩矩地对方法进行声明。但在Java8之后,我们可以使用Lambda简化对SamType的调用进行简化:
public interface IBuy {
void onBuy(double money);
}
public static void main(String[] args) {
buyBike(money -> System.out.println("buyBike:" + money));
buyCar(money -> System.out.println("buyCar:" + money));
}
public static void buyBike(IBuy buy) {
buy.onBuy(500.00);
}
public static void buyCar(IBuy buy) {
buy.onBuy(50000.00);
}
我们将上述借助Lambda对SamType调用的优化称为SAM转换(Single Abstract Method Conversions)
Kotlin兼容Java中的SAM转换
fun main() {
TestJavaSam.buyBike { money: Double -> println("buyBike:$money") }
TestJavaSam.buyCar { money: Double -> println("buyCar:$money") }
}
Kotlin将Java的SamType翻译成了lambda,因此在kotlin的同名方法实际变成了一个高阶函数:
buyBike(IBuy buy)
- >
fun buyBike(f:(ITEM) -> Unit)
SAM构造方法
fun main() {
//方案一:匿名类对象
buyBike(object : IBuy {
override fun onBuy(money: Double) {
println("buyBike:$money")
}
})
//方案二:SAM构造方法(推荐)
buyBike(IBuy {
println("buyBike:$it")
})
//方案三:SAM构造方法(推荐)
buyBike({
println("buyBike:$it")
})
//方案四:SAM构造方法(推荐)
buyBike {
println("buyBike:$it")
}
}
fun buyBike(buy: IBuy) {
buy.onBuy(500.00)
}