Kotlin Operator Overloading

In this article, you will learn about operator overloading (define how operator works for user defined types like objects) with the help of examples.

When you use operator in Kotlin, it's corresponding member function is called. For example, expression a+b transforms to a.plus(b) under the hood.

fun main(args: Array<String>) {
    val a = 5
    val b = 10

    print(a.plus(b)) // print(a+b)
}

When you run the program, the output will be:

15

In fact, plus() function is overloaded to work with various Kotlin basic types and String.

// + operator for basic types
operator fun plus(other: Byte): Int
operator fun plus(other: Short): Int
operator fun plus(other: Int): Int
operator fun plus(other: Long): Long
operator fun plus(other: Float): Float
operator fun plus(other: Double): Double

// for string concatenation
operator fun String?.plus(other: Any?): String

You can also define how operator works for objects by overloading its corresponding function. For example, you need define how + operator works for objects by overloading plus() function.

Example: Overloading + Operator

fun main(args: Array<String>) {
    val p1 = Point(3, -8)
    val p2 = Point(2, 9)

    var sum = Point()
    sum = p1 + p2

    println("sum = (${sum.x}, ${sum.y})")
}

class Point(val x: Int = 0, val y: Int = 10) {

    // overloading plus function
    operator fun plus(p: Point) : Point {
        return Point(x + p.x, y + p.y)
    }
}

When you run the program, the output will be:

sum = (5, 1)

Here, the plus() function is marked with operator keyword to tell compiler that + operator is being overloaded.

The expression p1 + p2 is transformed to p1.plus(p2) under the hood.


Example: -- Operator Overloading

In this example, you will learn to overload -- operator. The expression --a is transformed to a.dec() under the hood.

The dec() member function doesn't take any arguments.

fun main(args: Array<String>) {
    var point = Point(3, -8)
    --point

    println("point = (${point.x}, ${point.y})")
}

class Point(var x: Int = 0, var y: Int = 10) {
    operator fun dec() = Point(--x, --y)
}

When you run the program, the ouput will be:

point = (2, -9)

Remember that,

operator fun dec() = Point(--x, --y)

is equivalent to

operator fun dec(): Point {
    return Point(--x, --y)
}

Few Important Points

1. When you overload operators, you should try to maintain the original spirit of the operator. For example,

fun main(args: Array<String>) {
    val p1 = Point(3, -8)
    val p2 = Point(2, 9)

    var sum = Point()
    sum = p1 + p2

    println("sum = (${sum.x}, ${sum.y})")
}

class Point(val x: Int = 0, val y: Int = 10) {

    // overloading plus function
    operator fun plus(p: Point) = Point(x - p.x, y - p.y)
}

Although the program above is technically correct, we have used + operator to subtract corresponding properties of two objects which made the program confusing.

2. Unlike languages like Scala, only a specific set of operators can be overloaded in Kotlin. Visit the page to learn about operators that can be overloaded in Kotlin and their corresponding member functions.