Genişletme fonksiyonları/extension functions — mevcut sınıflara miras alma veya sınıfı değiştirme gereği olmadan yeni fonksiyonlar eklemeyi sağlayan bir mekanizmadır.
Örneğin, String sınıfına bir fonksiyon ekleyerek stringi tersine çevirelim:
fun String.reverse(): String { return this.reversed() } println("abc".reverse()) // "cba"
Genişletmeler aslında sınıfı modifiye etmez, sadece sözdizimsel bir şeker niteliğindedir: bunlar, nesnenin bir örneğini ilk parametre olarak kabul eden statik metotlar olarak derlenir.
Avantajları: kısa ve öz, okunabilirlik, kodun genişletilebilirliği. Koleksiyonlar, stringler vb. için utilite fonksiyonları olarak iyi bir şekilde eklenir.
İnce noktalar:
Genişletme fonksiyonları ile bir sınıfa durumu saklayan yeni bir değişken (property) eklemek mümkün mü?
Cevap: Hayır. Genişletme property’si her zaman hesaplanan bir özelliktir (getter/setter), alan değildir. Durumu saklayamazlar — sadece anlık hesaplarlar.
val String.secondChar: Char get() = this[1] // Sadece hesaplama, saklama değil!
Hikaye
Veri doğrulama projesinde bir geliştirici model sınıfına genişletme property’si ekledi; bunun bir değer sakladığı gibi düşündü, ama sonra değerin her zaman hesaplandığını fark etti; bu nedenle mantık, çoklu çağrılarda yanlış çalıştı.
Hikaye
Büyük bir uygulamada genişletmeler sınıfın yöntemleriyle aynı isimde adlandırıldı; bu karışıklığa yol açtı: sınıf yöntemleri her zaman önceliğe sahipti, genişletmeler çağrılmadı — "görünmeyen" kodun hata ayıklamasına bir gün harcandı.
Hikaye
Bir kütüphanede genişletmeler sınıfın özel alanları için kullanıldı, ama daha sonra bunların özel üyelere erişim izninin olmadığı anlaşıldı; bu durum model mimarisinin yeniden yapılandırılmasına neden oldu.