Kotlin OOP: Mengenal Getter dan Setter
Getter dan Setter merupakan 2 fitur Kotlin yang berhubungan dengan Properti. Dengan ini kita bisa menggubah perilaku properti dari sebuah kelas. Mari kita bahasa satu per satu.
Backing Field
Sebelum membahas getter dan setter alangkah baiknya kita mengenal dulu backing field. Pada Kotlin, Backing field merupakan bagian dari properti yang menyimpan nilai dari properti.
Saat kita mengakses nilai dari properti, maka akan diberikan nilai dari backing field milik properti. Ini adalah getter bawaan dari properti. Saat kita menentukan (mengubah) nilai dari properti, maka nilai dari backing field milik properti akan diubah menjadi nilai yang ditentukan. Ini adalah setter bawaan dari properti.
Getter
Getter merupakan fungsi yang menentukan nilai yang diberikan saat nilai suatu properti diakses.
Fungsi yang dijadikan getter harus diberi nama get
. Getter harus dideklarasikan di bawah properti.
Getter bisa digunakan pada properti mutable (var) maupun immutable (val). Karena nilai dari kedua properti tersebut sama-sama bisa diakses.
Berikut adalah contohnya:
class Orang(var namaAwal: String, var namaAkhir: String) {
val namaPanjang: String
get() {
println("Getter namaPanjang dipanggil")
return "$namaAwal $namaAkhir"
}
}
Fungsi yang di sorot adalah getter dari properti namaPanjang
.
Saat nilai dari namaPanjang
diakses maka kode di dalam get()
akan dipanggil dan akan diberikan
nilai yang dikembalikan fungsi get()
. Dengan kata lain nilai dari dari namaPanjang
akan selalu
"$namaAwal $namaAkhir"
.
Contoh penggunaan adalah seperti ini:
val orang = Orang("Ibnu", "Umar")
println(orang.namaPanjang)
orang.namaAwal = "Toni"
orang.namaAkhir = "Awal"
println(orang.namaPanjang)
/*
Getter namaPanjang dipanggil
Ibnu Umar
Getter namaPanjang dipanggil
Toni Awal
*/
Kita juga dapat membuat fungsi Getter di atas menjadi lebih ringkas dengan menggunakan single expression function. Jadinya seperti ini:
class Orang(var namaAwal: String, var namaAkhir: String) {
val namaPanjang: String
get() = "$namaAwal $namaAkhir"
}
Setter
Setter merupakan fungsi yang dipanggil saat suatu properti nilainya diubah. Dengan ini kita bisa
mengubah nilai properti jika nilai properti lain berubah. Fungsi yang dijadikan setter harus diberi
nama set
. Pada setter terdapat 1 parameter yang berisi nilai yang diberikan kepada properti.
Setter hanya bisa digunakan pada properti mutable (var). Karena hanya properti jenis ini yang nilainya dapat diubah.
Berikut adalah contohnya:
class Orang(var namaAwal: String, var namaAkhir: String) {
var namaPanjang: String = "$namaAwal $namaAkhir"
set(value) {
val namaSplit = value.split(" ", limit = 2)
namaAwal = namaSplit[0]
namaAkhir = namaSplit[1]
}
}
Pada contoh di atas saat nilai dari properti namaPanjang
diubah maka nilai nilai dari properti
namaAwal
dan namaAkhir
juga ikut berubah. Parameter value
pada setter berisi nilai yang
diberikan kepada properti namaPanjang
. Kata pertama di namaPanjang
dianggap sebagai nama awal
dan sisanya dianggap nama akhir.
Fungsi split
digunakan untuk memecah String menjadi Array menggunakan delimiter .
split(" ", limit = 2)
akan memecah String menggunakan spasi sebagai delimiter dan membatasi
hasilnya menjadi 2.
Berikut penggunaannya:
val orang = Orang("Ibnu", "Abbas")
println(orang.namaAwal) // Ibnu
println(orang.namaAkhir) // Abbas
orang.namaPanjang = "Sunan Ampel"
println(orang.namaAwal) // Sunan
println(orang.namaAkhir) // Ampel
println(orang.namaPanjang) // Ibnu Abbas
Pada baris kode terakhir terlihat jika nilai dari namaPanjang
tidak berubah. Kenapa bisa begitu?.
Padahal pada baris kode sebelumnya kita mengubah nilai namaPanjang
.
Masalah ini disebabkan karena pada setter kita tidak mengubah nilai dari backing field. Padahal
saat kita mengakses nilai dari namaPanjang
akan diberikan nilai dari backing field milik
namaPanjang
. Pada saat mendeklarasikan setter kita memiliki tanggung jawab untuk mengubah backing
field.
Nilai dari backing field hanya bisa diubah dari dalam setter dengan cara menentukan nilai dari
field
. Untuk mengatasi permasalahan di atas, tambahkan kode berikut ke baris setter yang terakhir:
set(value) {
// ...
field = value
}
Kita bisa coba lagi:
val orang = Orang("Ibnu", "Abbas")
orang.namaPanjang = "Sunan Ampel"
println(orang.namaPanjang) // Sunan Ampel
Ada satu permasalahan lagi contoh di atas. Permasalahannya adalah saat kita mengubah nilai dari
namaAwal
atau namaAkhir
, nilai namaPanjang
tidak berubah.
println(orang.namaPanjang) // Ibnu Abbas
orang.namaAwal = "Raden"
println(orang.namaPanjang) // Ibnu Abbas
Untuk mengatasi permasalahan seperti itu, kita bisa menggunakan getter dan setter secara bersamaan.
Menggunakan Getter dan Setter Bersamaan
Getter dan Setter juga bisa digunakan secara bersamaan. Getter dan Setter hanya bisa digunakan secara bersamaan pada variabel mutable (var).
Berikut penerapannya untuk mengatasi permasalahan pada contoh sebelumnya:
class Orang(var namaAwal: String, var namaAkhir: String) {
var namaPanjang: String
get() = "$namaAwal $namaAkhir"
set(value) {
val namaSplit = value.split(" ", limit = 2)
namaAwal = namaSplit[0]
namaAkhir = namaSplit[1]
}
}
Pada contoh tersebut, kita tidak perlu mengubah backing field pada setter. Karena saat kita
mengakses nilai dari namaPanjang
, nilai yang diberikan bukan nilai dari backing field tetapi
nilai dari getter.
Berikut contoh penggunaan:
val orang = Orang("Jovana", "Michael")
println(orang.namaPanjang) // Jovana Michael
orang.namaAwal = "Raditya"
orang.namaAkhir = "Dika"
println(orang.namaPanjang) // Raditya Dika
orang.namaPanjang = "Anggiat Sahat"
println(orang.namaAwal) // Anggiat
println(orang.namaAkhir) // Sahat
println(orang.namaPanjang) // Anggiat Sahat