Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Kotlin Dictionary

  1. Home
  2. Kotlin Dictionary
  3. Operator Overloading

Operator Overloading

Since: Kotlin 1.0(2016)

In Kotlin, you can redefine operators (+, -, *, [], (), etc.) for your own classes using the operator keyword. Operator overloading lets you work with objects using intuitive notation.

Syntax

data class Point(val x: Int, val y: Int) {
    // Overload the + operator
    operator fun plus(other: Point): Point = Point(x + other.x, y + other.y)

    // Overload the - operator
    operator fun minus(other: Point): Point = Point(x - other.x, y - other.y)

    // Unary minus
    operator fun unaryMinus(): Point = Point(-x, -y)
}

Operator list

OperatorFunction nameDescription
+aunaryPlus()Unary plus.
-aunaryMinus()Unary minus.
a + bplus(b)Addition.
a - bminus(b)Subtraction.
a * btimes(b)Multiplication.
a / bdiv(b)Division.
a % brem(b)Remainder.
a[i]get(i)Index access.
a[i] = vset(i, v)Index assignment.
a()invoke()Function call.
a in bcontains(a)Containment check.
a..brangeTo(b)Range creation.

Sample code

sample_operator_overloading.kt
data class Vector(val x: Double, val y: Double) {
    operator fun plus(other: Vector) = Vector(x + other.x, y + other.y)
    operator fun minus(other: Vector) = Vector(x - other.x, y - other.y)
    operator fun times(scale: Double) = Vector(x * scale, y * scale)
    operator fun unaryMinus() = Vector(-x, -y)

    // Overloading invoke() lets you call the object like a function (returns magnitude)
    operator fun invoke(): Double = Math.sqrt(x * x + y * y)

    override fun toString() = "($x, $y)"
}

// Advanced use case
class Matrix2x2(val a: Double, val b: Double, val c: Double, val d: Double) {
    // Access elements with [] (row and col are zero-based)
    operator fun get(row: Int, col: Int): Double = when {
        row == 0 && col == 0 -> a
        row == 0 && col == 1 -> b
        row == 1 && col == 0 -> c
        else -> d
    }
}

fun main() {
    val v1 = Vector(3.0, 4.0)
    val v2 = Vector(1.0, 2.0)

    println(v1 + v2) // (4.0, 6.0)
    println(v1 - v2) // (2.0, 2.0)
    println(v1 * 2.0) // (6.0, 8.0)
    println(-v1) // (-3.0, -4.0)
    println(v1()) // 5.0 (magnitude: √(9+16))

    val mat = Matrix2x2(1.0, 2.0, 3.0, 4.0)
    println(mat[0, 0]) // 1.0
    println(mat[1, 1]) // 4.0
}

The command looks like this:

kotlinc sample_operator_overloading.kt -include-runtime -d sample_operator_overloading.jar
java -jar sample_operator_overloading.jar
(4.0, 6.0)
(2.0, 2.0)
(6.0, 8.0)
(-3.0, -4.0)
5.0
1.0
4.0

Common Mistakes

// forgetting the operator keyword
data class Score(val value: Int) {
    fun plus(other: Score): Score = Score(value + other.value) // missing operator
}

fun main() {
    val s1 = Score(120)
    val s2 = Score(90)
    // val s3 = s1 + s2 // Compile error: unresolved reference: plus
    val s3 = s1.plus(s2) // Regular function call still works
    println(s3) // Score(value=210)

    // defining times(Double) and then trying to multiply by Int
    // val v = Vector(1.0, 2.0) * 3 // Compile error: operator fun times(scale: Double), Int not accepted
}

Common mistake 2 is not implementing Comparable when trying to use > or <. The correct approach is shown below.

sample_operator_overloading_ok.kt
// Definition with operator keyword
data class DeathNotes(val count: Int) {
    operator fun plus(other: DeathNotes): DeathNotes = DeathNotes(count + other.count)
}

// Implementing Comparable enables comparison operators
data class Intelligence(val iq: Int) : Comparable<Intelligence> {
    override fun compareTo(other: Intelligence): Int = iq - other.iq
}

fun main() {
    val d1 = DeathNotes(1)
    val d2 = DeathNotes(2)
    println(d1 + d2) // DeathNotes(count=3)

    val light = Intelligence(167)
    val l_lawliet = Intelligence(212)
    println(light < l_lawliet) // true
}

The command looks like this:

kotlinc sample_operator_overloading_ok.kt -include-runtime -d sample_operator_overloading_ok.jar
java -jar sample_operator_overloading_ok.jar
DeathNotes(count=3)
true

Notes

Operator overloading is especially powerful for classes that represent mathematical concepts such as numeric calculations, coordinates, matrices, and complex numbers. Using operators in non-obvious ways can lead to confusion, so overloading is commonly applied when the meaning is immediately clear from the operator's mathematical or domain-specific intent.

Overloading invoke() lets you call an object as if it were a function. This is useful in DSLs and builder patterns.

For data class features, see data class. For class inheritance, see open / override.

If you find any errors or copyright issues, please .