Generics (Typy generyczne) cz.1

Kliknij i wspomóż mnie :)

Kotlin

Typy generyczne pozwalają stworzyć bardziej uniwersalny kod oraz uniknąć duplikacji klas o tych samych elementach konstrukcyjnych. Zapraszam do czytania.

Wstęp

W oficjalnej dokumentacji języka Kotlin na temat generyków dosyć szybko przechodzą do tłumaczenia zawiłości takich jak wildcards czy ograniczenia.

Ja w dwóch artykułach rozbiję treść na podstawę oraz wytłumaczenie owych zawiłości w Kotlin'ie.

Na początku zobaczmy jak wygląda definicja podstawowych elementów takich jak funkcje i klasy.

Generyczna klasa Shop przyjmuje dowolną klasę jako parametr wejściowy i wypisuje jej nazwę. Jako, że typ T jest rozszerzony przez Any to mogłaby się tutaj również znaleźć klasa zupełnie nie związana ze sklepami.

Dzięki typom generycznym kompilator wie jakich klas używamy przez co w lini 13 ominąłem Operator diamentowy.

W funkcjach zaraz po słowie kluczowym fun deklarujemy typ parametru.

Variance

W przykładzie wyżej podkreśliłem, że do klasy Shop możemy podać klasę dowolnego typu co stwarza pewien problem. My chcemy aby klasa Shop przyjmowała jedynie obiekty dziedziczące po Company.

Zanim jednak pokażę na przykładzie jak to może wyglądać, trzeba rozwiać tajemnicę wildcards.

W Javie typy generyczne są niezmienne to znaczy, iż np. w List od String nie jest podtypem List od Object.

W naszym języku rozwiążemy to za pomocą ograniczenia zestawu klas T: Company.

Tak wygląda interfejs Company oraz klasy, które go implementują.

A tak wygląda przykład wykorzystania:

Nie dość, że teraz akceptowane klasy na pewno będą obiektami dziedziczącymi po Company to dodatkowo możemy wywołać funkcję getName() w klasie generycznej Shop. Znacznie zabezpiecza to oraz upraszcza kod.

Wildcards

Autorzy języka mocno zwracają uwagę na problem dzikich kart w Javie. Fantastycznie zostało to opisane na stronie samouczekprogramisty.pl tutaj:

Typy generyczne w języku Java

Ja spróbuję opisać jaka jest różnica pomiędzy producentem, a konsumentem w krótkich żołnierskich słowach.

Od producenta ? extends E odczytujemy obiekty.

Do konsumenta ? super E możemy zapisywać obiekty

Out

Typ parametru T out w klasie lub interfejsie generyczny oznacza, że typem zwracanym przez funkcje będzie T.

Można nazwać go producentem bo interesuje nas ten typ, który z niego wyciągniemy.

Dzięki takiemu użyciu słowa out możemy przechować str w item i korzystać z metody nextT(). Adnotacja out pozwala tylko na wyjściowy parametr T.

In

Odwrotnie ma się sytuacja z in. W tym przypadku funkcje konsumują (przyjmują) parametry generyczne.

Przykład z dokumentacji Kotlin'a doskonale tłumaczy jak zachowuje się in. Jako, że Double dziedziczy po Number to możemy użyć compareTo().

Dziękuję Ci za przeczytanie tego materiału 😀 Jeżeli spodobało Ci się to o czym piszę, możesz sprawdzić więcej materiałów na blogu lub udostępnić znajomym. Będzie mi bardzo miło 😊

O mnie

Jestem młodym programistą, który dumnie dzierży wiele pasji takich jak bieganie czy piwowarstwo domowe. Jedną z nich jest także programowanie i o tym właśnie zamierzam tutaj pisać.

Zobacz więcej

Najnowsze posty

Kliknij i wspomóż mnie :)

Zostańmy w kontakcie

* Wymagane
Kliknij i wspomóż mnie :)
shop
Otwórz Sklep Play

Zachęcam Cię do odwiedzenia mojej strony na Google Play store i sprawdzenia wszystkich moich aplikacji.