How to create an anonymous implementation of an interface?

InterfaceKotlin

Interface Problem Overview


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.

Interface Solutions


Solution 1 - Interface

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 =
            this@union.contains(x, y) || another.contains(x, y)
    }

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

Solution 2 - Interface

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! :)

Solution 3 - Interface

it's possible with kotlin, it's just you have to add fun before the interface so would be like fun interface xx, it's called a functional interface, basically what it means is an interface with ONE function, which is what we usually want

https://kotlinlang.org/docs/fun-interfaces.html

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiongvlasovView Question on Stackoverflow
Solution 1 - InterfacegvlasovView Answer on Stackoverflow
Solution 2 - InterfaceFerran MaylinchView Answer on Stackoverflow
Solution 3 - InterfaceTootsieRockNRollView Answer on Stackoverflow