Te ćwiczenia są częścią kursu Kotlin dla programistów. Skorzystaj z tego kursu, jeśli będziesz wykonywać kolejno kilka ćwiczeń z programowania. W zależności od Twojej wiedzy możesz mieć dostęp do niektórych sekcji. Ten kurs jest przeznaczony dla programistów, którzy znają język zorientowany na obiekty i chcą się dowiedzieć Kotlina.
Wstęp
Dzięki nim dowiesz się, jak wyglądają zajęcia ogólne, funkcje i metody w Kotlinie.
Lekcje nie obejmują jednej przykładowej aplikacji, ale mają one na celu pogłębianie wiedzy. Między innymi należy jednak pamiętać o zależności od siebie. W połączeniu wiele z przykładów wykorzystuje motyw akwariowy. A jeśli chcesz zobaczyć pełne informacje o oceanarium, zapoznaj się z kursem Kotlin Bootcamp for Programmers (Ukocity) na platformie Udacity.
Co musisz wiedzieć
- Składnia funkcji, klas i metod Kotlin
- Jak utworzyć nową klasę w IntelliJ IDEA i uruchomić program
Czego się nauczysz
- Praca z klasami, metodami i funkcjami ogólnymi
Jakie zadania wykonasz:
- Utwórz klasę ogólną i dodaj ograniczenia
- Tworzenie typów
in
iout
- Tworzenie ogólnych funkcji, metod i rozszerzeń
Wprowadzenie do ogólnych informacji
Kotlin, podobnie jak wiele innych języków programowania, ma typy ogólne. Typ ogólny pozwala ustawić zajęcia ogólnie, dzięki czemu klasa jest znacznie bardziej elastyczna.
Załóżmy, że implementujesz klasę MyList
, która zawiera listę elementów. Jeśli nie chcesz używać ogólnych danych, musisz wdrożyć nową wersję MyList
dla każdego typu: jedną dla Double
, jedną dla String
, jedną dla Fish
. Korzystając z opcji ogólnych, możesz uczynić listę ogólną, więc będzie ona obsługiwać dowolny typ obiektu. To jak symbol wieloznaczny, który pasuje do wielu typów.
Aby zdefiniować typ ogólny, umieść nazwę T w nawiasach kątowych <T>
za nazwą klasy. (Możesz użyć innej litery lub dłuższej nazwy, ale konwencja typu ogólnego to T).
class MyList<T> {
fun get(pos: Int): T {
TODO("implement")
}
fun addItem(item: T) {}
}
Możesz odnieść się do obiektu T
, tak jakby był to typ normalny. Zwracany typ get()
to T
, a parametr addItem()
to T
. Oczywiście listy ogólne są bardzo przydatne, więc klasa List
jest wbudowana w Kotlin.
Krok 1. Utwórz hierarchię typów
W tym kroku utworzysz klasy do użycia w następnym kroku. Wcześniejsze seminaria były omówione podczas wcześniejszego ćwiczenia z programowania, ale oto krótkie omówienie.
- Aby zachować przejrzystość przykładu, utwórz nowy pakiet w sekcji src i nazwij go
generics
. - W pakiecie generic utwórz nowy plik
Aquarium.kt
. Dzięki temu możesz zmienić definicje przy użyciu tych samych nazw, nie powodując konfliktów, więc reszta kodu ćwiczenia pozostanie w tym pliku. - Utwórz hierarchię typów typów wody. Zacznij od ustawienia klasy
WaterSupply
jako klasyopen
, aby móc ją przypisać do innych klas. - Dodaj wartość logiczną
var
(needsProcessing
). Spowoduje to automatyczne utworzenie zmiennej właściwości wraz z metodą getter i seter. - Utwórz podkategorię
TapWater
, która przedłużaWaterSupply
i przekazujetrue
dlaneedsProcessing
, ponieważ woda do kranu zawiera dodatki, które są szkodliwe dla ryb. - W funkcji
TapWater
zdefiniuj funkcję o nazwieaddChemicalCleaners()
, która ustawianeedsProcessing
nafalse
po oczyszczeniu wody. WłaściwośćneedsProcessing
może zostać ustawiona jakoTapWater
, ponieważ domyślnie ma wartośćpublic
i jest dostępna dla podklas. Oto kompletny kod.
package generics
open class WaterSupply(var needsProcessing: Boolean)
class TapWater : WaterSupply(true) {
fun addChemicalCleaners() {
needsProcessing = false
}
}
- Utwórz jeszcze 2 podgrupy klasy
WaterSupply
o nazwieFishStoreWater
iLakeWater
.FishStoreWater
nie wymaga przetwarzania, aleLakeWater
należy filtrować za pomocą metodyfilter()
. Po zakończeniu filtrowania nie trzeba go ponownie przetwarzać, więc ustawfilter()
naneedsProcessing = false
.
class FishStoreWater : WaterSupply(false)
class LakeWater : WaterSupply(true) {
fun filter() {
needsProcessing = false
}
}
Jeśli potrzebujesz dodatkowych informacji, zapoznaj się z poprzednią lekcją dotyczącą dziedziczenia w Kotlinie.
Krok 2. Utwórz zajęcia ogólne
W tym kroku zmodyfikujesz klasę Aquarium
, aby obsługiwała różne rodzaje źródeł wody.
- W klasie Aquarium.kt zdefiniuj klasę
Aquarium
, a w nawiasach po jej nazwie wpisz<T>
. - Dodaj stałą właściwość
waterSupply
typuT
doAquarium
.
class Aquarium<T>(val waterSupply: T)
- Napisz funkcję o nazwie
genericsExample()
. Nie jest to element klasy, więc może znajdować się na najwyższym poziomie pliku, na przykład funkcjimain()
czy definicji klas. Utwórz w funkcjiAquarium
i przekaż mu parametrWaterSupply
. ParametrwaterSupply
jest parametrem ogólnym, dlatego musisz określić typ w nawiasach kątowych<>
.
fun genericsExample() {
val aquarium = Aquarium<TapWater>(TapWater())
}
- W lokalizacji
genericsExample()
Twój kod może uzyskać dostęp do oceanariumwaterSupply
. Ze względu na typTapWater
możesz wywołać polecenieaddChemicalCleaners()
bez przesyłania.
fun genericsExample() {
val aquarium = Aquarium<TapWater>(TapWater())
aquarium.waterSupply.addChemicalCleaners()
}
- Podczas tworzenia obiektu
Aquarium
możesz usunąć nawiasy kątowe i odstępy między nimi, bo Kotlin ma wpływ na typ. Nie ma więc powodu, żeby powtarzaćTapWater
przy tworzeniu instancji. Ten typ może być wywnioskowany przez argumentAquarium
. Nadal będzie miał wartośćAquarium
typuTapWater
.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
aquarium.waterSupply.addChemicalCleaners()
}
- Aby sprawdzić, co się dzieje, wydrukuj tekst
needsProcessing
przed nawiązaniem połączenia z numeremaddChemicalCleaners()
i po nim. Poniżej znajduje się ukończona funkcja.
fun genericsExample() {
val aquarium = Aquarium<TapWater>(TapWater())
println("water needs processing: ${aquarium.waterSupply.needsProcessing}")
aquarium.waterSupply.addChemicalCleaners()
println("water needs processing: ${aquarium.waterSupply.needsProcessing}")
}
- Dodaj funkcję
main()
, by wywołaćgenericsExample()
, uruchom program i obserwuj wyniki.
fun main() {
genericsExample()
}
⇒ water needs processing: true water needs processing: false
Krok 3. Określ bardziej szczegółowo
Ogólnie rzecz biorąc, można W tym kroku sprecyzujesz, co może zawierać klasa Aquarium
.
- W
genericsExample()
utwórzAquarium
, przekazując ciąg znakówwaterSupply
, a następnie wydrukuj oceanariumwaterSupply
.
fun genericsExample() {
val aquarium2 = Aquarium("string")
println(aquarium2.waterSupply)
}
- Uruchom program, aby sprawdzić wyniki.
⇒ string
W efekcie przekazany jest ciąg, bo Aquarium
nie może nałożyć żadnych ograniczeń na T.
typ dowolnego typu, w tym String
.
- W
genericsExample()
utwórz kolejnyAquarium
, przekazującnull
dlawaterSupply
. JeśliwaterSupply
ma wartość NULL, wydrukuj wartość"waterSupply is null"
.
fun genericsExample() {
val aquarium3 = Aquarium(null)
if (aquarium3.waterSupply == null) {
println("waterSupply is null")
}
}
- Uruchom program i obserwuj wyniki.
⇒ waterSupply is null
Po co dawać null
podczas tworzenia obiektu Aquarium
? Jest to możliwe, ponieważ domyślnie T
to skrót od wartości null (Any?
), czyli typ u góry hierarchii typów. Poniżej znajduje się tekst.
class Aquarium<T: Any?>(val waterSupply: T)
- Aby nie zezwalać na przekazywanie wartości
null
, zmień typT
naAny
, usuwając?
zaAny
.
class Aquarium<T: Any>(val waterSupply: T)
W tym kontekście zasada Any
jest nazywana ogólnym ograniczeniem. Oznacza to, że każdy typ T
można przekazać, o ile jest określony jako null
.
- Musisz jedynie upewnić się, że w przypadku właściwości
T
można przekazać tylko klasęWaterSupply
(lub jedną z jej podkategorii). ZastąpAny
wartościąWaterSupply
, aby zdefiniować bardziej ogólne ograniczenie.
class Aquarium<T: WaterSupply>(val waterSupply: T)
Krok 4. Dodaj kolejne sprawdzanie
Na tym etapie poznasz funkcję check()
, która pomoże Ci upewnić się, że kod działa zgodnie z oczekiwaniami. Funkcja check()
jest standardową biblioteką w Kotlinie. Działa jako potwierdzenie i zwraca IllegalStateException
, jeśli argument ma wartość false
.
- Dodaj metodę
addWater()
do klasyAquarium
, aby dodać wodę, oraz właściwośćcheck()
, która zapewnia, że nie będzie trzeba najpierw jej przetwarzać.
class Aquarium<T: WaterSupply>(val waterSupply: T) {
fun addWater() {
check(!waterSupply.needsProcessing) { "water supply needs processing first" }
println("adding water from $waterSupply")
}
}
W tym przypadku, jeśli needsProcessing
ma wartość true (prawda), check()
zgłasza wyjątek.
- W systemie
genericsExample()
dodaj kod, by utworzyćAquarium
zLakeWater
, a potem dodaj do niego wodę.
fun genericsExample() {
val aquarium4 = Aquarium(LakeWater())
aquarium4.addWater()
}
- Uruchom program, a otrzymasz wyjątek, ponieważ woda musi zostać najpierw odfiltrowana.
⇒ Exception in thread "main" java.lang.IllegalStateException: water supply needs processing first at Aquarium.generics.Aquarium.addWater(Aquarium.kt:21)
- Dodaj wywołanie, aby filtrować wodę przed dodaniem jej do urządzenia
Aquarium
. Od tej pory nie ma wyjątków.
fun genericsExample() {
val aquarium4 = Aquarium(LakeWater())
aquarium4.waterSupply.filter()
aquarium4.addWater()
}
⇒ adding water from generics.LakeWater@880ec60
W tym artykule znajdziesz podstawowe informacje o generałach. Poniżej znajdziesz więcej informacji na ten temat. Zastanów się jednak, jak zadeklarować klasę ogólne i jak z niej korzystać.
W tym zadaniu poznasz typy rozpoczęcia i zakończenia związane z ogólnymi zasadami. Typ in
można przekazać tylko do klasy, a nie zwrócić. Typ out
to typ, który może zostać zwrócony tylko z klasy.
W klasie Aquarium
możesz zobaczyć, że typ ogólny jest zwracany tylko podczas pobierania usługi waterSupply
. Nie ma żadnych metod, które przyjmowały wartość typu T
jako parametr (z wyjątkiem definiowania jej w konstruktorze). Kotlin umożliwia definiowanie typów out
dokładnie w tym przypadku i ustala dodatkowe informacje o tym, gdzie można ich bezpiecznie używać. I podobnie możesz definiować typy in
w przypadku typów ogólnych, które kiedykolwiek są przekazywane do metod, a nie zwracane. Dzięki temu Kotlin może przeprowadzić dodatkową kontrolę bezpieczeństwa kodu.
Typy in
i out
to dyrektywy systemu Kotlin. Wyjaśnienie całego systemu typów jest poza zakresem tego kursu (jest on dość skomplikowany). Jednak kompilator może oznaczyć typy, które nie są odpowiednio oznaczone in
i out
, więc musisz o nich wiedzieć.
Krok 1. Zdefiniuj typ typu wyjściowego
- W klasie
Aquarium
zmieńT: WaterSupply
na typout
.
class Aquarium<out T: WaterSupply>(val waterSupply: T) {
...
}
- W tym samym pliku poza klasą zadeklaruj funkcję
addItemTo()
, która oczekujeAquarium
zWaterSupply
.
fun addItemTo(aquarium: Aquarium<WaterSupply>) = println("item added")
- Zadzwoń pod numer
addItemTo()
(genericsExample()
) i uruchom program.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
addItemTo(aquarium)
}
⇒ item added
Kotlin może zagwarantować, że addItemTo()
nie będzie wykonywać żadnych działań niebezpiecznych w typie WaterSupply
, ponieważ zadeklarowano go jako typ out
.
- Jeśli usuniesz słowo kluczowe
out
, kompilator wywoła błąd podczas wywoływania metodyaddItemTo()
, ponieważ Kotlin nie może zagwarantować, że nie wykonujesz niczego, co jest niebezpieczne dla tego typu.
Krok 2. Określ typ reklamy
Typ in
jest podobny do typu out
, ale w przypadku typów ogólnych, które nigdy nie są przekazywane do funkcji, nie zostały zwrócone. Jeśli spróbujesz zwrócić typ in
, wystąpi błąd kompilatora. W tym przykładzie określisz typ in
jako część interfejsu.
- W witrynie Aquarium.kt zdefiniuj interfejs
Cleaner
, który używa ogólnego typuT
, który jest ograniczony doWaterSupply
. Ponieważ jest używany tylko jako argument funkcjiclean()
, możesz ustawić go jako parametrin
.
interface Cleaner<in T: WaterSupply> {
fun clean(waterSupply: T)
}
- Aby użyć interfejsu
Cleaner
, utwórz klasęTapWaterCleaner
, która implementujeCleaner
do czyszczeniaTapWater
, dodając środki chemiczne.
class TapWaterCleaner : Cleaner<TapWater> {
override fun clean(waterSupply: TapWater) = waterSupply.addChemicalCleaners()
}
- W klasie
Aquarium
zaktualizujaddWater()
, aby pobierałCleaner
typuT
, i wyczyść go przed dodaniem.
class Aquarium<out T: WaterSupply>(val waterSupply: T) {
fun addWater(cleaner: Cleaner<T>) {
if (waterSupply.needsProcessing) {
cleaner.clean(waterSupply)
}
println("water added")
}
}
- Zmień przykładowy kod
genericsExample()
, abyTapWaterCleaner
,Aquarium
zTapWater
, a następnie dodaj trochę wody, używając środka czyszczącego. W razie potrzeby spowoduje to użycie czyszczenia.
fun genericsExample() {
val cleaner = TapWaterCleaner()
val aquarium = Aquarium(TapWater())
aquarium.addWater(cleaner)
}
Kotlin użyje informacji typu in
i out
, aby upewnić się, że kod wykorzystuje ogólne dane. Typy Out
i in
są łatwe do zapamiętania: typy out
można przekazywać na zewnątrz jako wartości zwrotne, a typy in
– do wewnątrz jako argumenty.
Jeśli chcesz dowiedzieć się więcej o rodzajach i typach błędów, zapoznaj się z dokumentacją na ich temat.
W ramach tego zadania dowiesz się więcej o funkcjach ogólnych i o tym, kiedy ich używać. Zazwyczaj utworzenie funkcji ogólnej jest dobrym pomysłem za każdym razem, gdy funkcja przyjmuje argument klasy klasy ogólnego.
Krok 1. Utwórz funkcję ogólną
- W icsics/Aquarium.kt utwórz funkcję
isWaterClean()
, która zajmujeAquarium
. Musisz określić ogólny typ parametru. Jedną z opcji jest użycieWaterSupply
.
fun isWaterClean(aquarium: Aquarium<WaterSupply>) {
println("aquarium water is clean: ${aquarium.waterSupply.needsProcessing}")
}
Oznacza to jednak, że element Aquarium
musi mieć parametr typu out
, aby można było go wywołać. Czasami użycie właściwości out
lub in
jest zbyt restrykcyjne, bo zarówno w danych wejściowych, jak i w wynikach musisz użyć typu. Wymagania dotyczące funkcji out
możesz usunąć, ustawiając tę funkcję jako ogólną.
- Aby funkcja była ogólna, stosuj nawiasy kątowe po słowie kluczowym
fun
, podając typ ogólnyT
i wszystkie ograniczenia, w tym przypadkuWaterSupply
. Zmień typ ograniczeniaAquarium
, który ma być ograniczony przezT
zamiastWaterSupply
.
fun <T: WaterSupply> isWaterClean(aquarium: Aquarium<T>) {
println("aquarium water is clean: ${!aquarium.waterSupply.needsProcessing}")
}
T
to parametr typu isWaterClean()
używany do określania ogólnego typu akwarium. Ten schemat jest bardzo powszechny i dobrze jest poświęcić chwilę na zapoznanie się z jego treścią.
- Wywołaj funkcję
isWaterClean()
, określając typ w nawiasach kątowych tuż po nazwie funkcji i przed nawiasami.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
isWaterClean<TapWater>(aquarium)
}
- Ze względu na skojarzenie typu z argumentem
aquarium
typ nie jest potrzebny, więc go usuń. Uruchom program i obserwuj wyniki.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
isWaterClean(aquarium)
}
⇒ aquarium water is clean: false
Krok 2. Utwórz metodę ogólną o zregenerowanym typie
Możesz też używać funkcji ogólnych w metodach, nawet w zajęciach z własnym typem ogólnym. W tym kroku dodasz do metody Aquarium
metodę ogólną, która sprawdza, czy ma ona typ WaterSupply
.
- W klasie
Aquarium
zadeklaruj metodęhasWaterSupplyOfType()
, która przyjmuje parametr ogólnyR
(T
jest już używany), ograniczony doWaterSupply
i zwracatrue
, jeśliwaterSupply
ma typR
. To jest funkcja zadeklarowana wcześniej, ale w klasieAquarium
.
fun <R: WaterSupply> hasWaterSupplyOfType() = waterSupply is R
- Zauważ, że ostatnie
R
jest podkreślone na czerwono. Najedź na niego kursorem, aby zobaczyć, co jest nie tak. - Aby przeprowadzić weryfikację
is
, musisz poinformować Kotlin, że typ jest zreformowany lub prawdziwy i można go użyć w funkcji. Aby to zrobić, wpiszinline
przed słowem kluczowymfun
, areified
przed typem ogólnymR
.
inline fun <reified R: WaterSupply> hasWaterSupplyOfType() = waterSupply is R
Gdy typ zostanie zmodyfikowany, możesz go używać jako zwykłego typu – jest to rzeczywisty typ po wbudowaniu. Oznacza to, że za pomocą typu możesz sprawdzić is
.
Jeśli nie użyjesz tu typu reified
, typ nie będzie „prawdziwy” dostatecznie, by Kotlin zezwolić na sprawdzanie is
. Dzieje się tak, ponieważ typy niezrealizowane są dostępne tylko w momencie kompilacji i nie mogą być używane w czasie działania programu. Więcej informacji znajdziesz w następnej sekcji.
- Jako typ podaj
TapWater
. Podobnie jak w przypadku funkcji ogólnych, należy wywoływać ogólne metody, stosując nawiasy kątowe z typem po nazwie funkcji. Uruchom program i obserwuj wyniki.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
println(aquarium.hasWaterSupplyOfType<TapWater>()) // true
}
⇒ true
Krok 3. Ustaw rozszerzenia
Tych typów wartości możesz też używać w przypadku zwykłych funkcji i rozszerzeń.
- Poza klasą
Aquarium
zdefiniuj wWaterSupply
funkcję rozszerzenia o nazwieisOfType()
, która sprawdza, czy przekazane zdarzenieWaterSupply
jest określonego typu, na przykładTapWater
.
inline fun <reified T: WaterSupply> WaterSupply.isOfType() = this is T
- Wywołaj funkcję rozszerzenia tak samo jak metoda.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
println(aquarium.waterSupply.isOfType<TapWater>())
}
⇒ true
Przy użyciu funkcji rozszerzenia nie ma znaczenia, jaki jest typ Aquarium
(Aquarium
, TowerTank
lub inna podklasa), o ile chodzi o atrybut Aquarium
. Składnia projekcji-gwiazdki to wygodny sposób określania różnych dopasowań. Korzystając z projekcji gwiazd, Kotlin zadba również o to, aby nie wykonywać żadnych niebezpiecznych działań.
- Aby użyć odwzorowania gwiazd, umieść
<*>
poAquarium
. Przenieś funkcjęhasWaterSupplyOfType()
jako funkcję rozszerzenia, ponieważ nie jest ona częścią podstawowego interfejsu API usługiAquarium
.
inline fun <reified R: WaterSupply> Aquarium<*>.hasWaterSupplyOfType() = waterSupply is R
- Zmień połączenie na
hasWaterSupplyOfType()
i uruchom program.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
println(aquarium.hasWaterSupplyOfType<TapWater>())
}
⇒ true
W poprzednim przykładzie konieczne było oznaczenie typu ogólnego jako reified
i umieszczenie funkcji inline
, ponieważ Kotlin musi wiedzieć o nich w czasie działania, a nie tylko w czasie kompilacji.
Kotlin korzysta z wszystkich typów ogólnych w czasie kompilowania. Dzięki temu kompilator upewni się, że wszystko jest bezpieczne. W czasie działania usuwane są wszystkie typy ogólne, dlatego poprzedni komunikat o błędzie dotyczący sprawdzania wykasowanego typu jest usuwany.
Okazuje się, że kompilator może utworzyć prawidłowy kod bez zachowania typów ogólnych do czasu działania. Oznacza to jednak, że czasami wykonujesz jakąś czynność, na przykład is
sprawdza ogólny typ treści, a kompilator nie jest w stanie jej obsłużyć. Z tego właśnie powodu Kotlin dodał prawdziwe i zaktualizowane typy.
Więcej informacji o zreformowanych typach i wymazywaniu typów znajdziesz w dokumentacji Kotlin.
Ta lekcja dotyczy ogólnych zagadnień, które są ważne, ponieważ wymagają większej elastyczności i łatwiejszego wykorzystania kodu.
- Utwórz klasy ogólne, aby zwiększyć elastyczność kodu.
- Dodaj ograniczenia ogólne, aby ograniczyć typy używane w przypadku ogólnych zasad.
- Używaj typów
in
iout
z typami ogólnymi, aby zwiększyć dokładność sprawdzania typu ograniczającego przekazywanie do klas lub zwracanie ich z zajęć. - Twórz ogólne funkcje i metody do pracy z typami ogólnymi. Przykład:
fun <T: WaterSupply> isWaterClean(aquarium: Aquarium<T>) { ... }
- Używaj ogólnych funkcji rozszerzeń, aby dodawać do klasy funkcje spoza zestawu podstawowego.
- Usunięte typy czasami są konieczne z powodu wymazania typu. W porównaniu z typami ogólnymi do czasu działania zachowują się typy kontrolowane.
- Użyj funkcji
check()
, aby sprawdzić, czy kod działa zgodnie z oczekiwaniami. Przykład:check(!waterSupply.needsProcessing) { "water supply needs processing first" }
Dokumentacja Kotlin
Jeśli chcesz dowiedzieć się więcej na dowolny temat dotyczący tego kursu lub nie wiesz, co zrobić, wejdź na https://kotlinlang.org.
- Ogólne
- Ograniczenia ogólne
- Odwzorowania gwiazd
- Typy
In
iout
- Zmienione parametry
- Wymazywanie typu
- Funkcja
check()
Samouczki Kotlin
Na stronie https://try.kotlinlang.org znajdziesz szczegółowe samouczki o nazwie Kotlin Koans, internetowe narzędzie do tłumaczenia, a także kompletny zestaw dokumentacji referencyjnej z przykładami.
Kurs Udacity
Kurs Udacity na ten temat znajdziesz na kursie Kotlin dla programistów.
IntelLIJ IDEA
Dokumentację IntelliJ IDEA znajdziesz na stronie JetBrains.
Ta sekcja zawiera listę możliwych zadań domowych dla uczniów, którzy pracują w ramach tego ćwiczenia w ramach kursu prowadzonego przez nauczyciela. To nauczyciel może wykonać te czynności:
- W razie potrzeby przypisz zadanie domowe.
- Poinformuj uczniów, jak przesyłać zadania domowe.
- Oceń projekty domowe.
Nauczyciele mogą wykorzystać te sugestie tak długo, jak chcą lub chcą, i mogą przypisać dowolne zadanie domowe.
Jeśli samodzielnie wykonujesz te ćwiczenia z programowania, możesz sprawdzić swoją wiedzę w tych zadaniach domowych.
Odpowiedz na te pytania.
Pytanie 1
Która z tych konwencji ma typową nazwę?
▢ <Gen>
▢ <Generic>
▢ <T>
▢ <X>
Pytanie 2
Ograniczenie typów dopuszczalnych w przypadku typów ogólnych nazywa się:
▢ ogólne ograniczenie
▢ ograniczenie ogólne
▢
▢ ogólny limit typów
Pytanie 3
Oznacza to:
▢ Obliczono rzeczywisty wpływ wykonania obiektu.
▢ Dla zajęć został ustawiony indeks z ograniczonym dostępem.
▢ Parametr ogólnego typu został zmieniony na prawdziwy.
▢ Zdalny wskaźnik błędu został aktywowany.
Przejdź do następnej lekcji:
Omówienie kursu, w tym linki do innych ćwiczeń z programowania, znajdziesz w artykule "Kotlin Bootcamp for Programmers: Witamy na kursie."