Operator Overloading
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
| Operator | Function name | Description |
|---|---|---|
| +a | unaryPlus() | Unary plus. |
| -a | unaryMinus() | Unary minus. |
| a + b | plus(b) | Addition. |
| a - b | minus(b) | Subtraction. |
| a * b | times(b) | Multiplication. |
| a / b | div(b) | Division. |
| a % b | rem(b) | Remainder. |
| a[i] | get(i) | Index access. |
| a[i] = v | set(i, v) | Index assignment. |
| a() | invoke() | Function call. |
| a in b | contains(a) | Containment check. |
| a..b | rangeTo(b) | Range creation. |
Sample code
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.
operator fun invoke(): Double = Math.sqrt(x * x + y * y) // magnitude
override fun toString() = "($x, $y)"
}
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
}
Notes
Operator overloading is especially powerful for classes that represent mathematical concepts such as numeric calculations, coordinates, matrices, and complex numbers. However, using operators in non-obvious ways can cause confusion, so it is recommended to overload operators only when the meaning is immediately clear.
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 contact us.