0Pricing
Kotlin Academy · Lekcja

Funkcje rozszerzające: składnia i reguły wyszukiwania

Pisz funkcje rozszerzające i poznaj semantykę statycznego wyszukiwania.

Funkcje rozszerzające: składnia i reguły wyszukiwania to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Kotlin Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Czym są funkcje rozszerzające

Funkcje rozszerzające pozwalają dodawać nowe funkcje do istniejących klas bez ich modyfikowania i bez używania dziedziczenia.

Podstawowa składnia funkcji rozszerzającej

Nazwę funkcji należy poprzedzić typem, który jest rozszerzany; ten typ nazywa się „typem odbiorcy”.
fun String.shout(): String = uppercase() + "!"
println("hello".shout())  // HELLO!
fun Int.isEven() = this % 2 == 0
println(4.isEven())  // true

this w rozszerzeniach

Wewnątrz funkcji rozszerzającej `this` odnosi się do obiektu odbiorcy.
fun List<Int>.secondOrNull(): Int? {
    return if (size >= 2) this[1] else null
}
println(listOf(10, 20, 30).secondOrNull())  // 20
println(listOf(5).secondOrNull())           // null

Statyczne wiązanie: rozszerzenia nie przesłaniają metod

Funkcje rozszerzające są rozwiązywane statycznie podczas kompilacji na podstawie zadeklarowanego typu — NIE są wirtualne.
open class Base
class Child : Base()
fun Base.greet() = "Hello from Base"
fun Child.greet() = "Hello from Child"

val obj: Base = Child()
println(obj.greet())  // "Hello from Base" (static dispatch!)

Rozszerzenia a funkcje składowe

Jeśli klasa ma funkcję składową o takim samym podpisie jak rozszerzenie, pierwszeństwo zawsze ma funkcja składowa.
class Greeter {
    fun hello() = "member hello"
}
fun Greeter.hello() = "extension hello"  // shadowed!
println(Greeter().hello())  // "member hello"

Funkcje rozszerzające dla odbiorcy dopuszczającego null

Można rozszerzać typy dopuszczające null. Wewnątrz rozszerzenia należy obsłużyć null za pomocą sprawdzeń `this == null`.
fun String?.orEmpty() = this ?: ""
fun Any?.toStringSafe() = this?.toString() ?: "null"
println(null.orEmpty())  // ""
println(42.toStringSafe())  // "42"

Widoczność i zakres

Rozszerzenia mogą być definiowane na najwyższym poziomie (globalnie), w klasie (jako rozszerzenia składowe) lub w pliku. Obowiązują je zwykłe zasady widoczności.
// Top-level extension:
fun List<String>.joinUppercase() = joinToString { it.uppercase() }
// Private to file:
private fun String.clean() = trim().lowercase()

Rozszerzenia companion object

Rozszerzenia można dodawać do companion object, aby rozszerzyć przestrzeń nazw na poziomie klasy.
class User(val name: String) {
    companion object
}
fun User.Companion.guest() = User("Guest")
val guest = User.guest()

Rozszerzenia typów biblioteki standardowej

Można rozszerzać dowolny typ — również typy wbudowane.
fun Double.roundTo(decimals: Int): Double {
    val factor = Math.pow(10.0, decimals.toDouble())
    return Math.round(this * factor) / factor
}
println(3.14159.roundTo(2))  // 3.14

Organizowanie rozszerzeń

Rozszerzenia danego typu należy grupować w osobnym pliku, np. StringExtensions.kt lub DateExtensions.kt.
// StringExtensions.kt
fun String.titleCase() = split(" ")
    .joinToString(" ") {
        it.replaceFirstChar { c -> c.uppercase() }
    }
println("hello world".titleCase())  // Hello World

Rozszerzenia nie mają dostępu do składowych prywatnych

Rozszerzenia mają dostęp tylko do składowych publicznych i internal — nie do prywatnych ani chronionych.
class Secret {
    private val key = "hidden"
    val name = "public"
}
fun Secret.reveal() {
    println(name)  // OK
    // println(key)  // Error: key is private
}

Szybkie sprawdzenie

Jeśli funkcja składowa klasy i funkcja rozszerzająca mają taki sam podpis, która z nich zostanie wywołana?

Podsumowanie

Funkcje rozszerzające dodają zachowanie do dowolnej klasy bez jej modyfikowania. Są wiązane statycznie (bez przesłaniania). Składowe mają pierwszeństwo przed rozszerzeniami. Odbiorców dopuszczających null należy używać do tworzenia pomocników bezpiecznych dla null. Dalej: właściwości rozszerzające!

Często zadawane pytania

Czy lekcja „Funkcje rozszerzające: składnia i reguły wyszukiwania” jest bezpłatna?

Tak — pełny tekst „Funkcje rozszerzające: składnia i reguły wyszukiwania” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Kotlin Academy, przejdź na CoddyKit PRO. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Funkcje rozszerzające: składnia i reguły wyszukiwania”?

Pisz funkcje rozszerzające i poznaj semantykę statycznego wyszukiwania. Ćwiczysz Kotlin Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Kotlin Academy?

Nie wymagamy żadnego doświadczenia. Kotlin Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „Funkcje rozszerzające: składnia i reguły wyszukiwania”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Kotlin Academy?

Tak. Każda lekcja Kotlin Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Funkcje rozszerzające: składnia i reguły wyszukiwania
  2. Właściwości rozszerzające i rozszerzenia obliczane
  3. Rozszerzenia o ograniczonym zakresie i rozszerzenia companion
  4. Praktyczne rozszerzenia: pomocnicze funkcje Context, View i String
← Powrót do Kotlin Academy