Kotlin-də genişləndirmə funksiyası: nədir, sintaksis və tətbiqi

Müəllif: IT Sectr Dərc olunub: 2026-06-21 Oxuma vaxtı: 9 dəq

genişləndirmə funksiyası — Kotlin mexanizmi, mövcud siniflərə miras almadan və mənbə kodunu dəyişmədən yeni metodlar əlavə etməyə imkan verir. Funksiya qəbuledici tip prefiksi ilə elan edilir və bu tipin adi metodu kimi çağırılır. Kotlin Documentation, 2025-ə görə, genişləndirmə funksiyaları birinci parametr-qəbuledici ilə statik metodlara kompilyasiya olunur və bu, adi çağırışlarla müqayisədə sıfır overhead təmin edir.

Əsas məqamlar

  • Genişləndirmə funksiyası — miras olmadan sinif üzvü kimi çağırılan qəbuledici tipli metod
  • Qəbuledici tip funksiya adından əvvəl nöqtə ilə göstərilir: fun Type.method()
  • Statik dispetçerləşdirmə — genişləndirmə funksiyası virtual deyil, dəyişən tipinə görə çağırılır
  • Import məcburidir: genişləndirmə funksiyaları sinif üzvü deyil və import tələb edir
  • Sinif üzvləri prioritetlidir: metod uyğun gələrsə, sinif üzvü çağırılır, genişləndirmə yox

Kotlin-də genişləndirmə funksiyası nədir?

Genişləndirmə funksiyası sinifdən kənarda elan edilmiş, lakin onun metodu kimi çağırılan funksiyadır. O, yeni metodun əlavə olunduğu qəbuledici tipi qəbul edir. Funksiya daxilində this açar sözü qəbuledici tipin nümunəsinə istinad edir. Bu yanaşma final sinifləri, üçüncü tərəf kitabxanalarının siniflərini və hətta primitiv tipləri sarğılar yaratmadan genişləndirməyə imkan verir.

Java-dan fərqli olaraq, mövcud sinifə metod əlavə etmək üçün ya miras, ya da statik yardımçı sinif tələb olunur, Kotlin boilerplate olmadan zərif həll təklif edir. Məlumatlara görə Kotlin Foundation (2024) tədqiqatında, genişləndirmə funksiyaları dilin ən çox istifadə olunan xüsusiyyətlərinin ilk beşliyinə daxildir — onu gündəlik işdə Kotlin tərtibatçılarının 78%-i tətbiq edir.

Kotlin kompilyatoru genişləndirmə funksiyasını statik metoda çevirir, burada birinci arqument kimi qəbuledici nümunəsi ötürülür. Bu o deməkdir ki, genişləndirmə funksiyaları hədəf sinfin bayt kodunu dəyişmir və inkapsulyasiyanı pozmur — qəbuledicinin yalnız açıq sahələri və metodları əlçatandır.

Genişləndirmə funksiyalarından məntiqi olaraq müəyyən tipə bağlı olan, lakin onun mənbə koduna əlavə edilə bilməyən təmiz yardımçı funksiyalar yazmaq üçün istifadə edin.

Genişləndirmə funksiyasının sintaksisi: elan və çağırış

Genişləndirmə funksiyasının əsas sintaksisi: qəbuledici tipin adı, nöqtə, funksiya adı, sonra parametrlər və qaytarılan tip. Funksiya daxilində qəbuledici this vasitəsilə əlçatandır.

kotlin
// String üçün genişləndirmə funksiyası
fun String.isEmail(): Boolean {
    return this.contains("@") && this.contains(".")
}

// Adi String metodu kimi çağırılır
val result = "user@example.com".isEmail() // true

Bu nümunədə isEmail() bütün sətirlər üçün əlçatan olur. Funksiya daxilində this metodun çağırıldığı sətirin özüdür. Kotlin əksər hallarda this-i buraxmağa imkan verir — this.contains("@") əvəzinə sadəcə contains("@") yazmaq olar.

Parametrlərlə genişləndirmə funksiyası

Genişləndirmə funksiyaları əlavə parametrlər qəbul edə və istənilən tipdə dəyər qaytara bilər. Bu onları sadəcə sintaktik şəkər deyil, tam hüquqlu funksiyalar edir.

kotlin
fun List<Int>.defaultIfEmpty(default: Int): List<Int> {
    if (this.isEmpty()) return listOf(default)
    return this
}

val populated = listOf(1, 2).defaultIfEmpty(0)
val empty = listOf<Int>().defaultIfEmpty(0)

default parametri boş siyahı üçün qaytarılan dəyəri müəyyən edir. Genişləndirmə funksiyası generic ola bilər — List tipi ümumiləşdirilmişdir, baxmayaraq ki, nümunədə konkret List istifadə olunur.

Statik dispetçerləşdirmə və qəbuledici

Kotlin-də genişləndirmə funksiyaları statik dispetçerləşdirmədən istifadə edir, virtual yox. Bu, adi sinif metodlarından əsas fərqdir. Hansı genişləndirmə funksiyasının çağırılacağı kompilyasiya mərhələsində dəyişənin statik tipinə görə müəyyən edilir, onun icra zamanı faktiki tipinə görə yox.

kotlin
open class Animal
class Dog : Animal()

fun Animal.speak() = "Heyvan səsi"
fun Dog.speak() = "Hürmək"

fun test() {
    val animal: Animal = Dog()
    println(animal.speak()) // "Heyvan səsi" — statik tip Animal

    val dog: Dog = Dog()
    println(dog.speak()) // "Hürmək" — statik tip Dog
}

Dəyişən animal Dog nümunəsinə işarə etsə də, Animal üçün genişləndirmə funksiyası çağırılır, çünki dəyişənin statik tipi Animal-dır. Əgər speak() sinfin virtual metodu olsaydı, Dog.speak() çağırılardı. Bu xüsusiyyət genişləndirmə funksiyaları üzərində API layihələndirərkən nəzərə alınmalıdır.

Genişləndirmə funksiyalarının importu və görünmə sahəsi

Genişləndirmə funksiyaları sinif üzvü deyil — bunlar adi funksiyalardır və başqa faylda istifadə üçün import tələb edir. Kotlin iki import variantı təklif edir: funksiya adı ilə və ya adın dəyişdirilməsi ilə.

kotlin
// Ada görə import
import com.example.extensions.isEmail

// Alias ilə import (konfliktləri həll etmək üçün)
import com.example.extensions.isEmail as isValidEmail

// İmportdan sonra çağırış
val valid = "test@test.com".isEmail()

Adın dəyişdirilməsi as vasitəsilə ad konfliktlərində faydalıdır — məsələn, iki kitabxana eyni tip üçün eyni adlı genişləndirmə funksiyası təqdim edərsə. Bu halda onlardan birini başqa adla import edib yeni adla çağırmaq olar.

Görünmə sahəsi

Genişləndirmə funksiyaları müxtəlif səviyyələrdə elan edilə bilər:

SəviyyəGörünməNümunə
Top-levelİmportdan sonra bütün layihəfun String.isEmail()
Member extensionSahib sinif daxilindəclass A { fun B.ext() }
LocalFunksiya daxilindəfun test() { fun String.ext() }

Member extension functions — genişləndirmə funksiyasının başqa sinif daxilində elan edildiyi xüsusi haldır. Bu halda genişləndirmə funksiyası daxilində həm qəbuledici (funksiyanın this-i), həm də xarici sinfin üzvləri əlçatandır.

Sinif üzvlərinin genişləndirmələr üzərində prioriteti

Əgər sinfin genişləndirmə funksiyası ilə eyni imzaya malik metodu varsa, həmişə sinif üzvü çağırılır. Genişləndirmə funksiyası heç vaxt sinif metodunu ləğv etmir — bu təsadüfi ləğvlərin qarşısını almaq üçün memarlıq qərarıdır.

kotlin
class User {
    fun greet() = "Salam sinifdən"
}

fun User.greet() = "Hello from extension"

fun main() {
    val user = User()
    println(user.greet()) // "Salam sinifdən"
}

Genişləndirmə funksiyası daha sonra təyin edilsə və eyni imzaya malik olsa belə, kompilyator sinif metodunu seçəcək. Kotlin kompilyatoru belə bir vəziyyət aşkar edildikdə xəbərdarlıq göstərir. Sinif metodu mövcud olduqda genişləndirmə funksiyasını çağırmağın yeganə yolu ona adi funksiya kimi müraciət etməkdir: greet(user).

Genişləndirmə funksiyalarının praktiki nümunələri

Android tərtibatında genişləndirmə funksiyaları View, Context və fraqmentlərlə iş üçün standart vasitəyə çevrilmişdir. Android KTX kitabxanası genişləndirmə funksiyaları üzərində qurulmuşdur, Android API üçün rahat sarğılar təmin edir.

kotlin
// View ilə iş üçün genişləndirmə funksiyası
fun View.show() {
    visibility = View.VISIBLE
}

fun View.hide() {
    visibility = View.GONE
}

// Context üçün genişləndirmə funksiyası — toast
fun Context.toast(message: String) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}

// DSL qurucu kimi genişləndirmə funksiyası
fun String.colorFormat(color: String): String =
    "$color$this\u001b[0m"

toast() genişləndirmə funksiyası Context-dən asılı çağırışları yığcam edir: Toast.makeText(context, message, length).show() yazmaq əvəzinə context.toast("Mətn") yazmaq kifayətdir. Bu, boilerplate-i azaldır və kodu daha oxunaqlı edir.

Tez-tez verilən suallar

Alt sinifdə genişləndirmə funksiyasını ləğv etmək olarmı?

Xeyr, genişləndirmə funksiyaları statik dispetçerləşdirmədən istifadə edir. Əgər baza sinfi və alt sinif üçün eyni genişləndirmə funksiyası elan edilərsə, hansının çağırılacağı kompilyasiya mərhələsində dəyişənin statik tipi ilə müəyyən edilir, icra zamanı faktiki tip ilə yox.

Genişləndirmə funksiyaları nullable tiplərlə necə işləyir?

Nullable qəbuledici tiplər üçün genişləndirmə funksiyaları elan etmək olar: fun String?.isNullOrEmail(). Belə funksiya daxilində this null ola bilər, buna görə də təhlükəsiz çağırış operatorlarından və ya açıq null yoxlamasından istifadə etmək lazımdır.

Genişləndirmə funksiyalarının performans overheadi varmı?

Xeyr, genişləndirmə funksiyaları statik metodlara kompilyasiya olunur. Bayt kodu səviyyəsində genişləndirmə funksiyasının çağırışı birinci parametr-qəbuledici ilə statik metod çağırışı ilə eynidir. Heç bir refleksiya və ya dinamik dispetçerləşdirmə yoxdur.

Sinif üçün genişləndirmə xassəsi elan etmək olarmı?

Bəli, genişləndirmə xassələri genişləndirmə funksiyaları kimi işləyir, lakin vəziyyət saxlaya bilməz — yalnız getter və setter. Məsələn: val List<Int>.sum get() = reduce(Int::plus). Onlar da getter/setter statik metodlarına kompilyasiya olunur.

Genişləndirmə funksiyaları Java yardımçı siniflərinin metodlarından nə ilə fərqlənir?

Java-da StringUtils.isEmail(str) yazırsan, Kotlin-də isə str.isEmail(). Fərq təkcə sintaksisdə deyil: genişləndirmə funksiyaları IDE-də avtomatik tamamlama dəstəkləyir, çağırış zəncirlərinin oxunaqlılığını yaxşılaşdırır və IDE-yə konkret tip üçün müvafiq funksiyalar təklif etməyə imkan verir. Java-da bu imkanlar yoxdur.

Nəticə

  • Genişləndirmə funksiyası — miras olmadan sinif üzvü kimi çağırılan qəbuledici tipli metod
  • Statik dispetçerləşdirmə — funksiyanın statik tipə görə seçilməsi, icra tipinə görə yox
  • Sıfır overhead — qəbuledici ilə birinci parametr kimi statik metoda kompilyasiya olunur
  • Import digər fayllarda istifadə üçün məcburidir, as vasitəsilə alias mümkündür
  • Sinif üzvləri eyni imzalı genişləndirmə funksiyaları üzərində prioritetə malikdir
  • Member extensions — sinif daxilində elan edilmiş genişləndirmələr, onun üzvlərinə girişi var
  • Praktiki tətbiq — String, View, Context, kolleksiyalar üçün alətlər və DSL quruculuğu

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun