Obiecałem i dotrzymuję! Kolejny fragmencik wiedzy dotyczący tym razem importowania pakietów albo jego części, o czym zaraz się przekonacie. Dalsza część poprzedniego artykułu. Poznajcie słowo kluczowe "import" w języku Kotlin w całej okazałości. Dodatkowy opis na co trzeba uważać w bonusie!
Tweet |
"IMPORT" W JĘZYKU KOTLIN DO...IMPORTOWANIA, BO DO CZEGO INNEGO?
Głupio tak pisać oczywiste sprawy jednak czasami trzeba. Jak można przypuszczać i nie trzeba do tego być geniuszem, "import" to instrukcja oznaczająca importowanie. Dokładniej to importowanie pakietu lub części pakietu. W praktyce oznacza to to, że będziemy mogli korzystać ze skróconych nazw klas pochodzących z innego pakietu, w aktualnym pliku źródłowym będącym także w innym pakiecie.
PRZYKŁAD KODU ŹRÓDŁOWEGO
Rozpatrzymy sytuację, w której wykorzystujemy "import" w języku Kotlin. Mamy trzy pliki źródłowe. Jeden nie należy do żadnego konkretnego pakietu (korzysta z domyślnego bez nazwy), a dwa kolejne należą do specyficznego pakietu. Oto ich treści:
import pl.jasonxiii.graphics.*
fun main(args: Array<String>) {
val point = Point(56, 78)
val entity = Entity(97, -3, "barrel")
println(point)
println(entity)
}
oraz
package pl.jasonxiii.graphics
open class Point(var x: Int = 0, var y: Int = 0) {
override fun toString() = "($x, $y)"
}
i do tego jeszcze:
package pl.jasonxiii.graphics
class Entity(x: Int, y: Int, var model: String) : Point(x, y) {
override fun toString() = "Model: $model ${super.toString()}"
}
Co możemy zauważyć? Import pakietu w jednym z plików u samej góry widoczny w instrukcji "import" w języku Kotlin (jeśli jest jeszcze instrukcja "package", to import umieszcza się poniżej niej zgodnie z konwencją). Najprościej jest zaimportować cały pakiet ze wszystkim w środku i o tym świadczy znak asterysku na samym końcu. Jeśli chcecie zaimportować jedynie fragment pakietu (klasę, klasę wyliczeniową, cokolwiek innego "pojedynczego"), to w miejsce asterysku wstawiacie pełną nazwę tego czegoś, co chcecie zapisywać skrótem:
import pl.jasonxiii.graphics.Point
import pl.jasonxiii.graphics.Entity
Pozostaje jeszcze Wam pokazać dlaczego importowanie nie jest robione na pokaz.
KORZYŚCI Z IMPORTU WIDOCZNE GOŁYM OKIEM
Kiedy definiujemy klasę w odrębnym pliku źródłowym, a on sam znajduje się w innym pakiecie, to jej nazwa jest wzbogacana o przedrostki, takie same jakie widać po instrukcji "package". Pisząc krótko, to:
Point
jeśli znajduje się w takim pakiecie:
pl.jasonxiii.graphics
to ta sama klasa już nosi następującą nazwę:
pl.jasonxiii.graphics.Point
Dziwicie się czemu robiony jest taki manewr? W artykule o samych pakietach, informowałem że GŁÓWNIE (czyli nie tylko) mają na celu ograniczenie występowania kolizji nazw. W związku z tym, jeśli w strukturze katalogów występuje rozróżnienie, to kod źródłowy musi także reflektować zgodnie z prawdą ścieżkę do klas w samych ich nazwach, które pochodzą od obcych pakietów.
PO TO TO WSZYSTKO
"import" w języku Kotlin daje nam taką korzyść, że pozwala uniknąć wprowadzania całej nazwy klasy pochodzącej z obcego pakietu. To trochę tak, jakbyśmy liczyli sztuki czegoś od samego początku, przerwali przed samym końcem, zanotowali na uboczu ile tego jest i po dłuższej przerwie kontynuowali liczenie, ale już od miejsca w którym zrobiło się pauzę. W ten sposób docieramy do sedna użyteczności, którym jest znowu SKRACANIE. Import oznacza skorzystanie z samej "gołej" nazwy klasy, tak jakby pochodziła ona z tego samego pliku źródłowego. Gdybyśmy odrzucili importowanie pakietu, to w każde miejsce występowania nazwy klasy z innego pakietu, trzeba by podawać kompletną nazwę klasy, czyli:
pl.jasonxiii.graphics.Point
Dwa czy trzy razy jeszcze spoko, natomiast jeśli mamy to samo wprowadzać po kilkanaście razy w jednym pliku, to już naprawdę ułatwcie sobie życie i podajcie na górze instrukcję importu.
ALIAS DLA IMPORTOWANYCH PAKIETÓW
Przy gigantycznych programach, może wystąpić sytuacja w której pomimo starannej organizacji pakietów, dochodzi do nieuniknionej kolizji nazw. Nie jesteśmy skazani na pokorne wprowadzanie pełnych nazw klas wybranego jednego z dwóch pakietów celem uniknięcia kolizji. Do dyspozycji mamy jeszcze dodatkowe słówko kluczowe "as", dzięki któremu nakładamy alias dla ciągu katalogów pakietu. Stosuje się go tak:
import pl.jasonxiii.graphics.Entity as EntityAlias
a używa się go wówczas tak (tylko dla klas pochodzących od tego pakietu, na nazwę którego nałożono alias):
val entity = EntityAlias(97, -3, "barrel")
Raz nałożony alias będzie obowiązywał w całym pliku źródłowym, tego również bądźcie świadomi. Zazwyczaj nie trzeba po to sięgać jednak jakby była potrzeba, skorzystajcie.
WYJAŚNIJMY SOBIE JESZCZE JEDNO
STOP! Możecie się zastanawiać: "a dlaczego w pewnych sytuacjach wykorzystuje się kod z zewnątrz i nie trzeba jakoś importować?". To prawda, nie trzeba. A to dlatego, że niektóre pakiety są już importowane "z automatu". Dlatego przykładowo, kiedy macie ochotę na skorzystanie ze zbioru modyfikowalnego, żaden import w języku Kotlin nie jest konieczny (mimo faktu, iż "MutableSet" należy do pakietu "collections"). Oto pełna lista:
- kotlin.*
- kotlin.annotation.*
- kotlin.collections.*
- kotlin.comparisons.*
- kotlin.io.*
- kotlin.ranges.*
- kotlin.sequences.*
- kotlin.text.*
- java. lang.* (jeśli platforma docelowa to JVM)
- kotlin.jvm.* (jeśli platforma docelowa to JVM)
- kotlin.js.* (jeśli platforma docelowa to JavaScript)
"import" otwiera drogę do korzystania ze skróconej nazwy klasy będącej w innym pakiecie, tak jakby jej definicja znajdowała się w tym samym pliku.
I to koniec importowanych zagrywek. "import" w języku Kotlin jedynie i aż uprzyjemnia pisanie kodu, tak jak cała reszta innych "cukierków" zostawionych w składni języka. Powinien to być ciepło przyjęty temat. Daje niemałe korzyści i nie wymaga zagłębiania się w szczegóły na poziomie pracy doktorskiej.