Operator seperti +, *, dan in sudah ada di Kotlin untuk tipe primitif. Saat kita membuat tipe baru seperti Vektor atau Uang, kita sering ingin menjumlahkan dua instance dengan + agar kode terbaca natural. Kotlin menyediakan operator functions — function dengan nama khusus yang dapat dipanggil melalui simbol operator. Pada chapter ini kita akan mendefinisikan ulang +, *, dan in pada class Vektor.

Anatomi operator Function #

Keyword operator diletakkan sebelum fun. Nama function harus sesuai dengan operator yang ingin di-overload — plus untuk +, times untuk *, contains untuk in, dan seterusnya. Kompilator menerjemahkan a + b menjadi a.plus(b).

kotlin
data class Vektor(val x: Int, val y: Int) {
    operator fun plus(other: Vektor): Vektor {
        return Vektor(x + other.x, y + other.y)
    }

    operator fun times(skalal: Int): Vektor {
        return Vektor(x * skalal, y * skalal)
    }

    operator fun contains(other: Vektor): Boolean {
        return x == other.x && y == other.y
    }
}

fun main() {
    val a = Vektor(2, 3)
    val b = Vektor(4, 5)

    val c = a + b
    println("a + b = (${c.x}, ${c.y})")

    val d = a * 3
    println("a * 3 = (${d.x}, ${d.y})")

    val ada = a in listOf(a, b)
    println("Apakah a ada di daftar? $ada")
}

Output yang Dihasilkan:

text
a + b = (6, 8)
a * 3 = (6, 9)
Apakah a ada di daftar? true

Mari kita bedah baris per baris:

  1. operator fun plus(other: Vektor): Vektor: mendefinisikan operator +. Pemanggilan a + b diterjemahkan kompilator menjadi a.plus(b). Tipe kembalian bebas; di sini kita mengembalikan Vektor baru.
  2. operator fun times(skalal: Int): Vektor: mendefinisikan operator *. a * 3 menjadi a.times(3).
  3. operator fun contains(other: Vektor): Boolean: mendefinisikan operator in. a in listOf(a, b) menjadi listOf(a, b).contains(a), yang kemudian memanggil contains pada setiap elemen.
  4. a + b: pemanggilan operator terasa natural seperti penjumlahan matematika. Tanpa operator fun plus, pemanggilan ini akan ditolak kompilator.

Daftar Operator yang Dapat Di-overload #

Kotlin menyediakan daftar nama function tetap yang dipetakan ke operator. Berikut sebagian yang paling sering dipakai.

OperatorNama FunctionContoh Pemanggilan
+plusa + b
-minusa - b
*timesa * b
/diva / b
%rema % b
..rangeToa..b
incontainsa in b
[]get / seta[i]
()invokea()
<, >, <=, >=compareToa < b

Daftar lengkap tersedia di dokumentasi resmi Kotlin tentang operator overloading. Setiap operator memiliki kontrak tipe kembalian yang berbeda — misalnya compareTo wajib mengembalikan Int, sedangkan contains wajib mengembalikan Boolean.

Indeks dan Invoke #

Operator get dan set memungkinkan kita memakai tanda kurung siku [] pada instance tipe kita. Operator invoke memungkinkan instance dipanggil seperti function. Berikut contoh singkat.

kotlin Contoh: get, set, dan invoke
class Matriks2x2(var a: Int, var b: Int, var c: Int, var d: Int) {
    operator fun get(i: Int, j: Int): Int = when {
        i == 0 && j == 0 -> a
        i == 0 && j == 1 -> b
        i == 1 && j == 0 -> c
        else -> d
    }

    operator fun set(i: Int, j: Int, nilai: Int) {
        when {
            i == 0 && j == 0 -> a = nilai
            i == 0 && j == 1 -> b = nilai
            i == 1 && j == 0 -> c = nilai
            else -> d = nilai
        }
    }
}

class Pengali(val faktor: Int) {
    operator fun invoke(x: Int): Int = x * faktor
}

fun main() {
    val m = Matriks2x2(1, 2, 3, 4)
    println(m[0, 0])   // 1
    m[1, 1] = 9
    println(m[1, 1])   // 9

    val kaliTiga = Pengali(3)
    println(kaliTiga(10))   // 30
}

Pemanggilan m[0, 0] diterjemahkan menjadi m.get(0, 0). Pemanggilan m[1, 1] = 9 diterjemahkan menjadi m.set(1, 1, 9). Pemanggilan kaliTiga(10) diterjemahkan menjadi kaliTiga.invoke(10).

compareTo dan Operator Relasional #

Operator compareTo mengembalikan Int negatif, nol, atau positif. Kotlin menerjemahkan a < b, a > b, a <= b, dan a >= b menjadi pemanggilan compareTo dengan interpretasi tanda hasil.

kotlin Contoh: compareTo untuk urutan
class Versi(val mayor: Int, val minor: Int) : Comparable<Versi> {
    override fun compareTo(other: Versi): Int {
        if (mayor != other.mayor) return mayor - other.mayor
        return minor - other.minor
    }
}

fun main() {
    val v1 = Versi(1, 5)
    val v2 = Versi(2, 0)
    println(v1 < v2)   // true
}

Implementasi Comparable<T> otomatis mengaktifkan operator <, >, <=, dan >= karena interface tersebut mewajibkan method compareTo.

Referensi Lanjutan #

Ringkasan #

Operator functions memungkinkan kita mendefinisikan ulang simbol seperti +, *, in, dan [] pada tipe buatan sendiri. Nama function harus persis sesuai daftar resmi Kotlin (plus, times, contains, get, set, compareTo, invoke, dan lainnya). Pemanggilan a + b diterjemahkan kompilator menjadi a.plus(b). Pada chapter Local Functions berikutnya, kita akan melihat bagaimana mendeklarasikan function di dalam function lain untuk menyembunyikan logika yang hanya relevan secara lokal.