The Kotlin Way: Coding approaches to implement interfaces
“The Kotlin Way” is a series of article where I describe ways to write commonly used code constructs and patterns in Kotlin.
This is the first article in the series, where I will show various techniques to implement intefaces from both Java as well as Kotlin libaries using Kotlin styles.

Inspiration
With many developers switching (or having to forcibly switch) from Java to Kotlin as part of the shift by Android, they are also realizing how wonderful and easy Kotlin is to write as well as comprehend. You’re probably used to the verbosity of Java 7 (And not used to using stuff like Lambdas a lot in Java 8). As a result, beginners might be finding Kotlin’s concise syntax, which is geared towards functional programmers, slightly unsettling.
Since Kotlin is fully interoperable with Java, codebases containing both can co-exist, you and write entire Kotlin projects using Java libraries, and so on.
This requires re-learning some of the ways of writing code & programming that we are used to, and this series aims to help you do just that.
Implementing intefaces from Java world
Lets say you want to implement an interface from a Java library which looks something like this
public interface Calculator<T> {
int add(T a, T b);
}
Approach #1: Classic
Lets look at the classic (boring) way of implementing this — Creating a named class.
// Kotlin Implementation #1
class IntegerCalculator : Calculator<Int> {
override fun add(a: Int, b: Int): Int {
return a + b
}
}// Invocation
val integerCalculator = IntegerCalculator()
integerCalculator.add(2, 3)
This is fine when you want to implement and interface with many methods and use the implementation in multiple areas.
Approach #2: Object expressions
Sometimes we need to create an instance of an inteface containing few and short methods, and pass this implementation to a specific function. Such interfaces are ubiquitous in the Android, for example: implementing event listeners. In Kotlin, you can handle such cases with object expressions
val integerCalculator = object : Calculator<Int> {
override fun add(a: Int, b: Int): Int {
return a + b
}
}print(integerCalculator.add(1, 2))
Note: The same style works when you extend classes as well, particularly when you want slight modifications of some class, without explicitly declaring a new subclass for it.
Approach #3: Uncle Sam in Java Interfaces
This is a special case for interfaces with only one abstract method (called functional interface, or a Single Abstract Method (SAM) interface).
In this case, you don’t have to manually create an named or anonymous class that implements it. Instead, you can use a lambda expression.
Using SAM conversion, Kotlin can transparently convert any lambda expression whose signature matches that of the interface’s single method into an instance of an anonymous class that implements the interface.
You can there write the following equivalent code to approach #1 and approach #2:
val integerCalculator = Calculator<Int> { a, b -> a + b }
integerCalculator.add(2, 3)
Bonus Tip: Many times, SAM interfaces contain methods with a single parmeter. While working with such interfaces, Kotlin allows you to omit the parameter in your lambda expression’s signature and use an implicit variable called it
in the expression's body.
Lets see this by having a single parameter method to our calculator interface, called square
public interface Calculator<T> {
T square(int x);
}
Object expressions approach
val integerCalculator = object : Calculator<Int>{
override fun square(x: Int): Int {
return x*x
}
}
integerCalculator.square(2)
The Kotlin Way: Passing in a lambda expression
val integerCalculator = Calculator { it * it }
integerCalculator.square(2)
As you can see, you don’t have to explicitly mention the ‘x’ parameter in your lambda expression’s signature. Instead, you can simply refer to it as it
Uncle Sam in Kotlin intefaces?
Looking at these example, you might be tempted to write SAM intefaces in Kotlin as well.
If you create a SAM interface in Kotlin, or create a Kotlin method that expects an object implementing a SAM interface as an argument, the SAM conversion facility will not be available to you — SAM conversion is a Java-interoperability feature and is limited to Java classes and interfaces only.
When you implement Kotlin functional interfaces, you will have to use the classic method or the slightly verbose object expression method
But that doesn’t make sense!
Why wouldn’t Kotlin provide this feature for its own language?! It didn’t, to me either — initially.
Because Kotlin supports higher-order functions — functions that can take other functions as arguments — you’ll never need to create SAM interfaces in it.
If you were to For example, if the Calculator
inteface is rewritten as below in Kotlin, we can pass in a function that squares the given type, and call this function in its square()
method.
class Calculator<T>(private val squareOperation: (x: T) -> T) {
fun square(x: T): T {
return squareOperation(x)
}
}// Invocation
val integerCalculator = Calculator<Int> { x -> x * x }
integerCalculator.square(2)
Now we are dipping our feet in FP land. Which looks like a very foreign place initially but the more places you visit, the more at-home you will feel! :)
Android’s APIs are largely written in Java, and many use SAM interfaces extensively. The same can be said of most third-party libraries too. By using the techniques you learned in this tutorial, you can work with them in your Kotlin code in a concise and easy-to-read way.
I emphasize: On reading, all of this looks alien but try it yourself in your IDE or online — that will really register the patterns in your brain.
If you found this post helpful and want more of these, give this article a clap and follow me on Twitter at _amolpednekar.
References (Official Documentation):
[1]https://kotlinlang.org/docs/reference/object-declarations.html