Setiap property Kotlin otomatis memiliki getter (untuk val dan var) dan setter (hanya untuk var). Saat kita menulis val x: Int = 5, kompilator menghasilkan getter default yang mengembalikan nilai field internal. Bila kita ingin mengubah perilaku pembacaan atau penugasan, Kotlin mengizinkan kita menulis custom accessor dengan sintaks ringkas. Pada chapter ini kita akan mempelajari custom getter, custom setter, dan computed property — property yang nilainya dihitung ulang setiap kali dibaca.
Custom Getter #
Custom getter ditulis dengan keyword get() di bawah deklarasi property. Setiap kali pemanggil membaca property, ekspresi di dalam getter dievaluasi. Computed property tidak memiliki backing field sendiri; nilainya dihitung berdasarkan property lain atau data eksternal.
class Lingkaran(var jariJari: Double) {
val luas: Double
get() = 3.14159 * jariJari * jariJari
}Property luas tidak menyimpan nilai apa pun. Setiap kali c.luas dipanggil, ekspresi 3.14159 * jariJari * jariJari dievaluasi ulang dengan nilai jariJari saat itu. Bila jariJari berubah, luas otomatis mengikuti.
Custom Setter #
Custom setter ditulis dengan keyword set(nilai). Parameter setter (lazimnya value atau nama deskriptif) menerima nilai yang ditugaskan pemanggil. Di dalam setter, kita dapat memvalidasi, mengubah property lain, atau menghitung nilai balik sebelum disimpan.
class Lingkaran(var jariJari: Double) {
var keliling: Double
get() = 2 * 3.14159 * jariJari
set(nilai) {
jariJari = nilai / (2 * 3.14159)
}
}Pemanggil c.keliling = 62.8318 tidak menyimpan 62.8318 ke field mana pun. Sebagai gantinya, setter menghitung jariJari = 62.8318 / (2 * 3.14159) = 10.0 dan menugaskannya ke property jariJari. Selanjutnya getter keliling akan mengembalikan nilai berdasarkan jariJari yang baru.
Contoh Lengkap dengan Tiga Accessor #
Contoh berikut memperlihatkan class Lingkaran dengan satu property biasa (jariJari), satu computed property (luas), dan dua property dengan getter+setter yang memanipulasi jariJari (keliling dan diameter). Setter diameter memuat validasi untuk memastikan nilai positif.
// property_accessors.kt
// Mendemonstrasikan custom getter/setter dan computed property.
class Lingkaran(var jariJari: Double) {
val luas: Double
get() = 3.14159 * jariJari * jariJari
var keliling: Double
get() = 2 * 3.14159 * jariJari
set(nilai) {
jariJari = nilai / (2 * 3.14159)
}
var diameter: Double
get() = 2 * jariJari
set(nilai) {
require(nilai > 0) { "Diameter harus positif" }
jariJari = nilai / 2
}
}
fun main() {
val c = Lingkaran(5.0)
println("Jari-jari: ${c.jariJari}")
println("Luas: ${c.luas}")
println("Keliling: ${c.keliling}")
println("Diameter: ${c.diameter}")
c.keliling = 62.8318
println("Setelah set keliling=62.8318, jari-jari: ${c.jariJari}")
c.diameter = 20.0
println("Setelah set diameter=20.0, jari-jari: ${c.jariJari}")
println("Luas akhir: ${c.luas}")
}Output yang Dihasilkan:
Jari-jari: 5.0
Luas: 78.53975
Keliling: 31.4159
Diameter: 10.0
Setelah set keliling=62.8318, jari-jari: 10.0
Setelah set diameter=20.0, jari-jari: 10.0
Luas akhir: 314.159Mari kita amati perilaku setiap accessor:
val luas: Double get() = ...: computed property tanpa backing field. Setiap kalic.luasdipakai, ekspresi mengalikanjariJarisaat itu dengan3.14159.var keliling: Doubledengan getter+setter: getter menghitung darijariJari; setter menerima nilai baru, lalu mengubahjariJariagar konsisten. Tidak ada fieldkelilingyang disimpan.c.keliling = 62.8318: pemanggilan setter dengan argumen62.8318. Setter menghitungjariJari = 62.8318 / (2 * 3.14159) ≈ 10.0.c.diameter = 20.0: pemanggilan setterdiameterdengan validasirequire(nilai > 0). Setelah lolos,jariJari = 20.0 / 2 = 10.0. Bila pemanggil mencobac.diameter = -5.0,IllegalArgumentExceptionakan dilempar.c.luasdi akhir: membaca propertyluassekali lagi. KarenajariJarisekarang10.0, hasilnya3.14159 * 10 * 10 = 314.159. PerubahanjariJariotomatis tercermin padaluas.
Computed Property vs Method #
Computed property sering setara dengan method tanpa argumen. Pilihan antara keduanya adalah masalah gaya:
| Aspek | Computed Property | Method |
|---|---|---|
| Sintaks pemanggilan | c.luas (tanpa kurung) | c.hitungLuas() |
| Komputasi ringan, tanpa efek samping | Cocok | Boleh |
| Komputasi berat atau I/O | Tidak disarankan | Lebih tepat |
Mengikuti konvensi Java (mis. size()) | Tergantung preferensi | Lazim |
Accessor dengan Backing Field #
Pada contoh diameter di atas, setter tidak menugaskan ke field melainkan ke property lain (jariJari). Bila kita ingin menyimpan nilai ke field internal sambil melakukan validasi, gunakan keyword field di dalam setter. Pembahasan mendalam tentang backing field akan menjadi fokus chapter Backing Fields berikutnya.
Referensi Lanjutan #
- Properties — bagian getter dan setter custom pada panduan property
Ringkasan #
Custom accessor memberi kontrol penuh atas pembacaan dan penugasan property tanpa mengurangi kesederhanaan sintaks. Custom getter mengubah nilai yang dikembalikan; custom setter mengubah nilai yang ditugaskan. Computed property adalah property tanpa backing field yang dihitung ulang setiap pembacaan. Pada chapter Backing Fields berikutnya, kita akan menelaah lebih dalam keyword field dan batasannya dalam custom accessor.