Rozszerzenia o ograniczonym zakresie i rozszerzenia companion
Ograniczaj widoczność rozszerzeń i dodawaj rozszerzenia do obiektów companion.
Rozszerzenia o ograniczonym zakresie i rozszerzenia companion to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 3 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.
Po co ograniczać zakres rozszerzeń
Domyślnie rozszerzenia są widoczne wszędzie tam, gdzie zostały zaimportowane. Ograniczenie zakresu do klasy, pliku lub kontekstu zmniejsza zaśmiecenie przestrzeni nazw i ułatwia odnajdywanie rozszerzeń.
Rozszerzenia prywatne dla pliku
Funkcję rozszerzającą na poziomie pliku należy oznaczyć jako private, aby ograniczyć ją tylko do tego pliku.
private fun String.shout() = uppercase() + "!"
fun main() {
println("hello".shout()) // HELLO!
}Widoczność internal
Należy używać internal, aby ograniczyć rozszerzenia do bieżącego modułu — to idealne rozwiązanie dla wewnętrznych elementów biblioteki, które nie są przeznaczone do użytku zewnętrznego.
internal fun List<Int>.sumIfPositive(): Int = filter { it > 0 }.sum()
fun main() {
println(listOf(-1, 2, 3, -4).sumIfPositive()) // 5
}Funkcje rozszerzające składowe
Rozszerzenie należy zadeklarować wewnątrz klasy, aby można było go używać tylko wtedy, gdy instancja tej klasy znajduje się w zakresie. Ma ono dwa odbiorce: dispatch (klasę) i rozszerzenia (element docelowy).
class StringHelper(val prefix: String) {
fun String.withPrefix() = prefix + this
fun build(): String = "world".withPrefix() // calls extension via instance
}
fun main() {
println(StringHelper("hello ").build()) // hello world
}Widoczność rozszerzeń składowych
Rozszerzenia składowe są niedostępne spoza klasy dispatch. Jest to przydatne do enkapsulacji.
class Repo {
fun List<Int>.allPositive() = all { it > 0 }
fun check(xs: List<Int>) = xs.allPositive()
}
fun main() {
val r = Repo()
println(r.check(listOf(1, 2, 3))) // true
// listOf(1).allPositive() // ERROR — no access
}Rozszerzenie companion object
Do companion object klasy można dodać rozszerzenie. Dla wywołującego wygląda ono jak metoda statyczna, ale znajduje się poza klasą.
class Greeter {
companion object
}
fun Greeter.Companion.morning() = "Good morning!"
fun main() {
println(Greeter.morning())
}Po co rozszerzenia companion
Są przydatne do dodawania metod fabrykujących lub pomocniczych spoza oryginalnej klasy — bez jej modyfikowania.
class User(val name: String) {
companion object
}
fun User.Companion.guest() = User("Guest")
fun User.Companion.system() = User("System")
fun main() {
println(User.guest().name)
println(User.system().name)
}Wymagany pusty companion
Klasa musi zadeklarować companion object (nawet pusty), aby można było do niego dołączyć rozszerzenia. W przeciwnym razie cel rozszerzenia nie istnieje.
class Box {
companion object // required, even if empty
}
fun Box.Companion.create(): Box = Box()
fun main() {
println(Box.create())
}Ograniczanie zakresu rozszerzeń za pomocą importów
Użycie rozszerzenia można ograniczyć, importując je tylko w określonych plikach. Pliki, które go nie importują, nie będą go widzieć.
// File A:
// fun String.shout() = uppercase()
// File B imports:
// import com.example.shout
// Only File B can call shout()
fun String.shout() = uppercase() + "!"
fun main() { println("hi".shout()) }Funkcja rozszerzająca za pomocą funkcji zakresu
Należy użyć with lub apply, aby tymczasowo wprowadzić obiekt do zakresu i użyć rozszerzenia.
class StringTools {
fun String.greet() = "Hello, $this!"
fun process(name: String) = with(this) {
name.greet()
}
}
fun main() {
println(StringTools().process("Ada"))
}Właściwości rozszerzające obiektu towarzyszącego
Rozszerzenia obiektu towarzyszącego mogą być również właściwościami — umożliwiają dodawanie nazwanych stałych spoza klasy.
class HttpStatus {
companion object
}
val HttpStatus.Companion.OK_CODE: Int get() = 200
val HttpStatus.Companion.NOT_FOUND: Int get() = 404
fun main() {
println(HttpStatus.OK_CODE)
println(HttpStatus.NOT_FOUND)
}Najlepsze praktyki
Należy używać private dla pomocniczych elementów lokalnych dla pliku, internal dla interfejsów dostępnych tylko w module, rozszerzeń składowych w celu hermetyzacji oraz rozszerzeń obiektu towarzyszącego do dodawania pomocniczych funkcji przypominających fabryki spoza klasy.
class StringUtils {
companion object
}
fun StringUtils.Companion.isAlpha(s: String) = s.all { it.isLetter() }
fun main() {
println(StringUtils.isAlpha("hello"))
println(StringUtils.isAlpha("hi5"))
}Szybkie sprawdzenie
Co jest wymagane w klasie, aby można było dodać do niej rozszerzenie obiektu towarzyszącego spoza klasy?
Podsumowanie
Należy ograniczać zakres rozszerzeń za pomocą private, internal lub definiować je jako rozszerzenia składowe wewnątrz klasy. Rozszerzenia obiektu towarzyszącego — funkcje lub właściwości — można dodawać spoza klasy, dołączając je do zadeklarowanego obiektu towarzyszącego tej klasy. Ogranicza to zanieczyszczanie przestrzeni nazw, a jednocześnie pomaga zachować modularność kodu.
Często zadawane pytania
Czy lekcja „Rozszerzenia o ograniczonym zakresie i rozszerzenia companion” jest bezpłatna?
Tak — pełny tekst „Rozszerzenia o ograniczonym zakresie i rozszerzenia companion” 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 „Rozszerzenia o ograniczonym zakresie i rozszerzenia companion”?
Ograniczaj widoczność rozszerzeń i dodawaj rozszerzenia do obiektów companion. Ć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 3 z 4.
Ile czasu zajmuje lekcja „Rozszerzenia o ograniczonym zakresie i rozszerzenia companion”?
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
- Funkcje rozszerzające: składnia i reguły wyszukiwania
- Właściwości rozszerzające i rozszerzenia obliczane
- Rozszerzenia o ograniczonym zakresie i rozszerzenia companion
- Praktyczne rozszerzenia: pomocnicze funkcje Context, View i String