如何创建接口的匿名实现?
How to create an anonymous implementation of an interface?
我有一个界面:
interface TileSet {
fun contains(x: Int, y: Int) : Boolean
}
我希望能够创建图块集的并集(图块是一对 x 和 y 整数坐标):
fun TileSet.union(another: TileSet) : TileSet =
// ..
在Java8中,我可以这样做:
@FunctionalInterface
public interface TileSet {
boolean contains(int x, int y);
public default TileSet unite(TileSet another) {
return (x, y) -> TileSet.this.contains(x, y) && another.contains(x, y);
}
}
因此在 TileSet#unite()
中使用 lambda 实现了一个接口。或者它可以用旧的匿名 class 方法实现:
public default TileSet unite(TileSet another) {
return new TileSet() {
@Override
public boolean contains(int x, int y) {
return TileSet.this.contains(x, y) && another.contains(x, y);
}
}
}
如何在 Kotlin 中创建单方法接口的匿名实现?
如果我使用 (Int, Int) -> Boolean
而不是 TileSet
,我知道该怎么做,但我希望该类型具有描述性名称而不仅仅是函数签名。
documentation 中有针对匿名 类 的示例,但没有针对接口的示例。
这就是我创建接口实例的方式:
fun TileSet.union(another: TileSet) : TileSet =
object : TileSet {
override fun contains(x: Int, y: Int) : Boolean =
this@union.contains(x, y) || another.contains(x, y)
}
请注意,与文档中的示例不同,object : TileSet
之后没有括号。
我做了一些实验,我惊讶地发现您可以使用 Kotlin lambdas 实现 Java 函数式接口:
// Implementing Java functional interfaces using lambdas
val greeter = Consumer<String> { println("Hi $it") }
val dice = Supplier { ThreadLocalRandom.current().nextInt(1, 7) }
但是当你实现Kotlin函数式接口时,你需要完整的仪式:
// Implementing a Kotlin functional inteface with lambdas is not possible
val greeter = object : MyConsumer<String> {
override fun accept(x: String) {
println("Hi $x")
}
}
@FunctionalInterface
interface MyConsumer<T> {
fun accept(x:T)
}
我想知道为什么在从非常 Kotlin 实现 Kotlin 接口时需要完整的匿名 class 语法!
也许他们希望您改用函数?可以这样做。
// If you want to use lambdas, define a function instead of an interface
val greeter: MyConsumerFunction<String> = { println("Hi $it") }
typealias MyConsumerFunction<T> = (T) -> Unit
不管怎样,如果有人知道这件事,请告诉我! :)
kotlin 是可以的,只是你必须在 interface
之前添加 fun
所以就像 fun interface xx
,它被称为功能接口,基本上它的意思是接口只有一个功能,这就是我们通常想要的
我有一个界面:
interface TileSet {
fun contains(x: Int, y: Int) : Boolean
}
我希望能够创建图块集的并集(图块是一对 x 和 y 整数坐标):
fun TileSet.union(another: TileSet) : TileSet =
// ..
在Java8中,我可以这样做:
@FunctionalInterface
public interface TileSet {
boolean contains(int x, int y);
public default TileSet unite(TileSet another) {
return (x, y) -> TileSet.this.contains(x, y) && another.contains(x, y);
}
}
因此在 TileSet#unite()
中使用 lambda 实现了一个接口。或者它可以用旧的匿名 class 方法实现:
public default TileSet unite(TileSet another) {
return new TileSet() {
@Override
public boolean contains(int x, int y) {
return TileSet.this.contains(x, y) && another.contains(x, y);
}
}
}
如何在 Kotlin 中创建单方法接口的匿名实现?
如果我使用 (Int, Int) -> Boolean
而不是 TileSet
,我知道该怎么做,但我希望该类型具有描述性名称而不仅仅是函数签名。
documentation 中有针对匿名 类 的示例,但没有针对接口的示例。
这就是我创建接口实例的方式:
fun TileSet.union(another: TileSet) : TileSet =
object : TileSet {
override fun contains(x: Int, y: Int) : Boolean =
this@union.contains(x, y) || another.contains(x, y)
}
请注意,与文档中的示例不同,object : TileSet
之后没有括号。
我做了一些实验,我惊讶地发现您可以使用 Kotlin lambdas 实现 Java 函数式接口:
// Implementing Java functional interfaces using lambdas
val greeter = Consumer<String> { println("Hi $it") }
val dice = Supplier { ThreadLocalRandom.current().nextInt(1, 7) }
但是当你实现Kotlin函数式接口时,你需要完整的仪式:
// Implementing a Kotlin functional inteface with lambdas is not possible
val greeter = object : MyConsumer<String> {
override fun accept(x: String) {
println("Hi $x")
}
}
@FunctionalInterface
interface MyConsumer<T> {
fun accept(x:T)
}
我想知道为什么在从非常 Kotlin 实现 Kotlin 接口时需要完整的匿名 class 语法!
也许他们希望您改用函数?可以这样做。
// If you want to use lambdas, define a function instead of an interface
val greeter: MyConsumerFunction<String> = { println("Hi $it") }
typealias MyConsumerFunction<T> = (T) -> Unit
不管怎样,如果有人知道这件事,请告诉我! :)
kotlin 是可以的,只是你必须在 interface
之前添加 fun
所以就像 fun interface xx
,它被称为功能接口,基本上它的意思是接口只有一个功能,这就是我们通常想要的