Pengelolaan properti kelas baik itu memberikan atau merubah sebuah nilai dapat didelegasikan kepada kelas lain. Dengan ini kita dapat meminimalisir boilerplate dalam penulisan getter dan setter (jika properties menggunakan var) pada setiap kelas yang kita buat. Sebagai contoh, kita memiliki tiga buah kelas yang di dalamnya memiliki satu properti String. Jika kita ingin menerapkan getter dan setter pada setiap properti kelasnya, maka kita perlu menuliskan getter dan setter tersebut pada seluruh kelas. Hal tersebut dapat mengurangi efisiensi dalam menuliskan kode karena terlalu banyak kode yang harus kita tulis secara berulang. Solusinya, kita perlu membuat sebuah kelas yang memang bertugas untuk mengatur atau mengelola fungsi getter dan setter untuk sebuah properti kelas. Teknik tersebut pada Kotlin dinamakan Delegate.

Sebelum mendelegasikan sebuah properti kita perlu membuat kelas delegasi terlebih dahulu. Mari kita buat sebuah kelas delegasi.

1. import kotlin.reflect.KProperty 2.   3.   4. class DelegateName { 5.     private var value: String = "Default" 6.   7.     operator fun getValue(classRef: Any?, property: KProperty<*>) : String { 8.         println("Fungsi ini sama seperti getter untuk properti ${property.name} pada class $classRef") 9.         return value 10.     } 11.   12.     operator fun setValue(classRef: Any?, property: KProperty<*>, newValue: String){ 13.         println("Fungsi ini sama seperti setter untuk properti ${property.name} pada class $classRef") 14.         println("Nilai ${property.name} dari: $value akan berubah menjadi $newValue") 15.         value = newValue 16.     } 17. }

Kemudian untuk mendelegasikan sebuah properti kelas, kita gunakan keyword by dalam menginisialisasi properti tersebut kemudian diikuti dengan namanya. Perhatikan kode berikut:

1. class Animal { 2.     var name: String by DelegateName() 3. }

Dengan begitu nilai properti name dikelola melalui kelas DelegateName. Kita dapat mendelegasikan banyak properti yang terdapat pada banyak kelas kepada satu kelas Delegate saja. Perhatikan kode berikut untuk untuk lebih jelasnya:

1. class Animal { 2.     var name: String by DelegateName() 3. } 4.   5. class Person { 6.     var name: String by DelegateName() 7. } 8.   9. class Hero { 10.     var name: String by DelegateName() 11. }

Mari kita membuat sebuah objek, ubah dan akses nilai propertinya pada setiap kelas, kemudian jalankan. Maka hasilnya akan seperti pada kode berikut:

1. fun main() { 2.     val animal = Animal() 3.     animal.name = "Dicoding Miaw" 4.     println("Nama Hewan: ${animal.name}") 5.   6.     val person = Person() 7.     person.name = "Dimas" 8.     println("Nama Orang: ${person.name}") 9.   10.     val hero = Hero() 11.     hero.name = "Gatotkaca" 12.     println("Nama Pahlawan: ${hero.name}") 13. } 14.   15. /* 16. output: 17.     Fungsi ini sama seperti setter untuk properti name pada class Animal@17f052a3 18.     Nilai name dari: Default akan berubah menjadi Dicoding Miaw 19.     Fungsi ini sama seperti getter untuk properti name pada class Animal@17f052a3 20.     Nama Hewan: Dicoding Miaw 21.     Fungsi ini sama seperti setter untuk properti name pada class Person@2e0fa5d3 22.     Nilai name dari: Default akan berubah menjadi Dimas 23.     Fungsi ini sama seperti getter untuk properti name pada class Person@2e0fa5d3 24.     Nama Orang: Dimas 25.     Fungsi ini sama seperti setter untuk properti name pada class Hero@5010be6 26.     Nilai name dari: Default akan berubah menjadi Gatotkaca 27.     Fungsi ini sama seperti getter untuk properti name pada class Hero@5010be6 28.     Nama Pahlawan: Gatotkaca 29. */

Pada contoh di atas, delegasi hanya dapat digunakan oleh properti yang memiliki tipe data String. Namun kita juga dapat membuat sebuah delegasi kelas umum yang dapat digunakan oleh seluruh tipe data dengan memanfaatkan tipe data Any.

1. class DelegateGenericClass { 2.     private var value: Any = "Default" 3.   4.     operator fun getValue(classRef: Any, property: KProperty<*>): Any { 5.         println("Fungsi ini sama seperti getter untuk properti ${property.name} pada class $classRef") 6.         return value 7.     } 8.   9.     operator fun setValue(classRef: Any, property: KProperty<*>, newValue: Any) { 10.         println("Nilai ${property.name} dari: $value akan berubah menjadi $newValue") 11.         value = newValue 12.     } 13. } 14.   15. class Animal { 16.     var name: Any by DelegateGenericClass() 17.     var weight: Any by DelegateGenericClass() 18.     var age: Any by DelegateGenericClass() 19. }

Kemudian mari kita membuat sebuah objek dari kelas Animal, ubah dan akses nilai propertinya kemudian jalankan. Maka hasilnya akan seperti pada kode berikut:

1. fun main(){ 2.     val animal = Animal() 3.     animal.name = "Dicoding cat" 4.     animal.weight = 6.2 5.     animal.age = 1 6.   7.     println("Nama: ${animal.name}") 8.     println("Berat: ${animal.weight}") 9.     println("Umur: ${animal.age} Tahun") 10. } 11.   12. /* 13. output: 14.     Nilai name dari: Default akan berubah menjadi Dicoding cat 15.     Nilai weight dari: Default akan berubah menjadi 6.2 16.     Nilai age dari: Default akan berubah menjadi 1 17.     Fungsi ini sama seperti getter untuk properti name pada class Animal@17f052a3 18.     Nama: Dicoding cat 19.     Fungsi ini sama seperti getter untuk properti weight pada class Animal@17f052a3 20.     Berat: 6.2 21.     Fungsi ini sama seperti getter untuk properti age pada class Animal@17f052a3 22.     Umur: 1 Tahun 23. */

Perhatikan kode diatas, kita telah memberikan nilai pada setiap properti dengan tipe data yang berbeda. Tetapi dengan DelegateGenericClass(), pengelolaan properti dapat digunakan pada seluruh tipe data properti.