skip to content

What is operator overloading in Kotlin, and how do you make the `+` symbol work on your own class?

level: juniorimportance: must knowfreq 70%

answer

  1. Symbol -> fixed-name function call
  2. `operator` modifier is required
  3. a + b == a.plus(b)
  4. Can be member or extension
  5. No new symbols, no precedence changes

basics

~20 s

Operator overloading lets symbols like + or [] work on your own types. You write a function with a fixed name (like plus) and mark it with the operator keyword. Then a + b calls a.plus(b).

solid answer

~40 s

Kotlin maps each operator symbol to a function with a fixed, conventional name. To enable `+`, you declare `operator fun plus(other: T): R` on the class (or as an extension). The `operator` modifier is mandatory; without it the compiler treats `plus` as an ordinary method and `a + b` won't compile. The compiler resolves operators purely by name and signature — `a + b` becomes `a.plus(b)`, `a[i]` becomes `a.get(i)`, `a()` becomes `a.invoke()`. You cannot invent new symbols or change precedence/associativity; you only give meaning to the existing fixed set (plus, minus, times, div, rem, get, set, invoke, compareTo, contains, rangeTo, inc, dec, etc.). Return type is free.

code

kotlin · 5 lines
kotlin
data class Money(val cents: Long) {
    operator fun plus(other: Money) = Money(cents + other.cents)
}

val total = Money(150) + Money(99)  // Money(249)

go deeper

for a junior

Knows operator fun plus enables + and that the keyword is required.

for a middle

Explains the name-based translation for several operators and member-vs-extension.

for a senior

Notes fixed precedence, return-type constraints on compareTo/contains, and when overloading aids readability vs. confuses.

for a principal

Frames operator overloading as a readability tool for value types, and sets team conventions to avoid surprising semantics.

## What operator overloading is Kotlin lets you give the built-in operator symbols (`+`, `-`, `*`, `[]`, `()`, `in`, `..`, `++`) a meaning for your own types. You do this by implementing a **function with a specific conventional name** and marking it with the **`operator`** modifier. The compiler translates operator syntax into a normal function call **by name**: - `a + b` -> `a.plus(b)` - `a - b` -> `a.minus(b)` - `a * b` -> `a.times(b)` - `a[i]` -> `a.get(i)` - `a[i] = v` -> `a.set(i, v)` - `a()` -> `a.invoke()` - `a in c` -> `c.contains(a)` - `a..b` -> `a.rangeTo(b)` ## The `operator` keyword is mandatory A function only participates in operator syntax if it is declared `operator`. Without it, the name `plus` is just a regular method and `a + b` is a compile error. ```kotlin data class Vec(val x: Int, val y: Int) { operator fun plus(other: Vec) = Vec(x + other.x, y + other.y) } val r = Vec(1, 2) + Vec(3, 4) // -> Vec(4, 6); compiler calls Vec(1,2).plus(Vec(3,4)) ``` ## Key rules - **Fixed names only.** You can't define brand-new symbols; you can only attach meaning to the existing operator set. - **Precedence and associativity are fixed** by the language and can't be changed. - **Member or extension.** An operator can be a member function or an `operator` extension function — useful for overloading operators on types you don't own. - **Return type is unrestricted** for arithmetic-like operators (`plus` can return any type). Some operators do constrain the return type — e.g. `compareTo` must return `Int`, `contains` must return `Boolean`. Operator overloading is purely syntactic sugar over named functions — it improves readability for value-like types (vectors, money, matrices, ranges) but does not add new runtime capability.

  • What happens if you write `fun plus(...)` without `operator`?
    `a + b` won't compile; you can still call `a.plus(b)` explicitly as a normal method, but the operator syntax is rejected.
  • Can you overload `+` for a class you don't own, like `String`?
    Yes — declare an `operator fun` as an extension, e.g. `operator fun String.plus(...)`, though redefining existing ones may be shadowed by built-ins.

Like teaching an existing word a new meaning in your dialect — you reuse the word '+', you don't invent a new letter.

saying these in an interview costs you the question

  • Thinking you can define entirely new operator symbols
  • Forgetting the `operator` keyword is required
  • Claiming you can change operator precedence
  • Believing operators must be members (extensions work too)

context