Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create an anonymous implementation of an interface?

I have an interface:

interface TileSet {     fun contains(x: Int, y: Int) : Boolean } 

I want to be able to create unions of sets of tiles (tile is a pair of x and y integer coordinates):

fun TileSet.union(another: TileSet) : TileSet =     // .. 

In Java 8, I could do it like this:

@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);     } } 

So an interface is implemented with a lambda in TileSet#unite(). Or it could be implemented with the old anonymous class approach:

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);          }     } } 

How can I create an anonymous implementation of a single-method interface in Kotlin?

I know how to do it if I use (Int, Int) -> Boolean instead of TileSet, but I want the type to have a descriptive name rather than just a function signature.

like image 676
gvlasov Avatar asked Nov 05 '15 18:11

gvlasov


People also ask

Can an anonymous class implement an interface?

A normal class can implement any number of interfaces but the anonymous inner class can implement only one interface at a time.

How do you make an interface class anonymous in Java?

Object = new Example() { public void display() { System. out. println("Anonymous class overrides the method display()."); } }; Here, an object of the anonymous class is created dynamically when we need to override the display() method.

What is anonymous implementation in Java?

Anonymous classes enable you to make your code more concise. They enable you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name. Use them if you need to use a local class only once.


2 Answers

There are examples in the documentation for anonymous classes, but not for interfaces.

This is how I created an instance of an interface:

fun TileSet.union(another: TileSet) : TileSet =     object : TileSet {         override fun contains(x: Int, y: Int) : Boolean =             [email protected](x, y) || another.contains(x, y)     } 

Notice that, unlike in the example from documentation, there are no parentheses after object : TileSet.

like image 94
gvlasov Avatar answered Sep 23 '22 10:09

gvlasov


I was experimenting a little bit, and I was surprised to find that you can implement Java functional interfaces using Kotlin lambdas:

// Implementing Java functional interfaces using lambdas val greeter = Consumer<String> { println("Hi $it") } val dice = Supplier { ThreadLocalRandom.current().nextInt(1, 7) } 

But when you implement Kotlin functional interfaces, you need the full ceremony:

// 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) } 

I wonder why the full anonymous class syntax is needed when implementing Kotlin intefaces from the very Kotlin!

Maybe they want you to use functions instead? That could be done like this.

// 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 

Anyway, if anyone knows anything about this, please let me know! :)

like image 39
Ferran Maylinch Avatar answered Sep 21 '22 10:09

Ferran Maylinch