Kotlin operator overloading explained with code examples

In Kotlin, type operators such as plus arithmetic operator (+) and minus arithmetic operator (-) call a corresponding function member to perform the intended operations.

For example, to calculate Int types of a + b Kotlin will call .plus() function underneath:

val a: Int = 5
val b: Int = 2

print(a + b) // a.plus(b) = 7

But notice how when you call the same + operator on String types, the operation changes from calculating the sum of two numbers into concatenating the letters:

val a: String = "Hello"
val b: String = " World"

print(a + b) // a.plus(b) = Hello World

This is possible because operator functions like .plus() are overloaded in Kotlin.

In the String class, the plus() function definition is as shown below:

public operator fun plus(other: Any?): String

But for Int class, the definition is like this:

public operator fun plus(other: Int): Int

This is what operator overloading is in Kotlin. It allows you to overload the member functions that are called by type operators.

With operator overloading, you can define what Kotlin will do when operators are called on your class or data class instances.

For example, suppose you have a User class with one property initialized from the constructor called name:

class User(val name: String)

Let’s create an object of User type and call the + operator to perform concatenation and see what happens:

val user = User("Nathan")

print(user + "Mr. ")

When you run the above code, Kotlin will throw an Unresolved reference error because the receiver type User is not known to Kotlin.

To resolve this error, you need to overload the plus() function.

To overload an operator function, you need to add the operator modifier before the fun keyword as shown below:

class User(val name: String) {
    operator fun plus(other: String): String {
        return this.name + other
    }
}

val user = User("Nathan")

print(user + " Sebhastian") // user.plus(" Sebhastian") = Nathan Sebhastian

With the plus() function being overloaded in the User class, the + operator now knows what to do when user.plus() is called.

Why operator overloading is useful

Operator overloading is useful because it allows Kotlin operators to have meanings for classes and types that you define in your source code.

Instead of just throwing an error because it doesn’t know what to do with your data type, operator overloading allows you to integrate custom-defined types as if they were built-in types.

Another example where operator overloading comes in handy is when you have a custom data type involving geometric shapes.

Suppose you have a Rectangle shape with length and width properties as shown below:

data class Rectangle(length: Int, width: Int)

You can override the unary minus operator - to transform both length and width properties to their equivalent negative values.

Add the unaryMinus() function to your data class definition as shown below:

data class Rectangle(val length: Int, val width: Int) {
    operator fun unaryMinus(): Rectangle {
        return Rectangle(-this.length, -this.width)
    }
}

Note that unaryMinus() is the function called when you place the minus operator before the variable name.

If you place the minus operator after the variable name, you need to overload the minus() function.

Here’s an example of calling unaryMinus() from Rectangle class:

val rec = Rectangle(8, 5)
val recMinus = -rec

println(recMinus.length) // -8
println(recMinus.width) // -5

Without operator overloading, you have to manually re-assign the property values.

Kotlin only allows you to overload a pre-defined set of operators. You can refer to Kotlin operator overloading documentation for a full list of operators that you can overload with their specific rules.

I hope this tutorial has helped you learn how operator overloading works in Kotlin. 🙏

Take your skills to the next level ⚡️

I'm sending out an occasional email with the latest tutorials on programming, web development, and statistics. Drop your email in the box below and I'll send new stuff straight into your inbox!

No spam. Unsubscribe anytime.