Typy ogólne

Typ ogólny to klasa ogólna lub interfejs, który jest sparametryzowany względem typów. Następująca klasa Box zostanie zmodyfikowana, aby zademonstrować tę koncepcję.

Prosta klasa Box

Rozpocznij od zbadania nieogólnej klasy Box, która działa na obiektach dowolnego typu. Musi tylko dostarczyć dwie metody: set, która dodaje obiekt do pudełka i get, która go pobiera:

Ponieważ jego metody akceptują lub zwracają obiekt, możesz swobodnie przekazać cokolwiek chcesz , pod warunkiem, że nie jest to jeden z typów pierwotnych. Nie ma możliwości sprawdzenia, w czasie kompilacji, jak ta klasa jest używana. Jedna część kodu może umieścić w polu liczbę całkowitą i oczekiwać, że z niej wyjdą liczby całkowite, podczas gdy inna część kodu może omyłkowo przekazać ciąg znaków, powodując błąd w czasie wykonywania.

Wersja ogólna klasy Box

Klasa ogólna ma następujący format:

class name<T1, T2, ..., Tn> { /* ... */ }

Aby zaktualizować Box, aby używać typów ogólnych, tworzysz deklarację typu ogólnego, zmieniając kod „public class Box” na „public class Box < T > ”. Wprowadza to zmienną typu T, której można użyć w dowolnym miejscu w klasie.

Po tej zmianie klasa Box staje się:

Jak widać, wszystkie wystąpienia Object są zastąpiona przez T. Zmienna typu może być dowolnym innym niż pierwotnym typem, który podasz: dowolnym typem klasy, dowolnym typem interfejsu, dowolnym typem tablicy lub nawet innym typem.

Tę samą technikę można zastosować do tworzenia ogólne interfejsy.

Konwencje nazewnictwa parametrów typu

Zgodnie z konwencją, nazwy parametrów typów są pojedynczymi dużymi literami. Kontrastuje to ostro z konwencjami nazewnictwa zmiennych, o których już wiesz, i nie bez powodu: bez tej konwencji trudno byłoby odróżnić zmienną typu od zwykłej nazwy klasy lub interfejsu.

Najczęściej używanymi nazwami parametrów typu są:

  • E – Element (szeroko używane w środowisku Java Collections Framework)
  • K – Key
  • N – liczba
  • T – typ
  • V – wartość
  • S, U, V itd. – 2, 3, 4 typy

Nazwy te będą używane w całym API Java SE i w pozostałej części tej lekcji.

Wywoływanie i tworzenie instancji typu ogólnego

Aby odwołać się do ogólnej klasy Box z poziomu kodu należy wykonać wywołanie typu ogólnego, które zastępuje T pewną konkretną wartością, taką jak Integer:

Box<Integer> integerBox;

Możesz myśleć o wywołaniu typu ogólnego jak o wywołaniu zwykłej metody, ale zamiast przekazywania argumentu do am ethod, przekazujesz argument typu – w tym przypadku Integer – do samej klasy Box.

Parametr typu i Argument typu Terminologia: Wielu programistów używa zamiennie terminów „parametr typu” i „argument typu”, ale te warunki nie są takie same. Podczas kodowania podaje się argumenty typu w celu utworzenia sparametryzowanego typu. Dlatego T w Foo < T > jest parametrem typu, a ciąg w Foo < String > f jest argumentem typu. W tej lekcji uwzględniono tę definicję podczas używania tych terminów.

Jak każda inna deklaracja zmiennej, ten kod w rzeczywistości nie tworzy nowego obiektu Box. Po prostu deklaruje, że integerBox będzie zawierał odniesienie do „Box of Integer”, czyli w ten sposób odczytywany jest Box < Integer >.

Wywołanie typu ogólnego jest ogólnie znane jako typ sparametryzowany.

Aby utworzyć instancję tej klasy, jak zwykle użyj słowa kluczowego new, ale umieść < Integer > między nazwą klasy a nawiasem:

Box<Integer> integerBox = new Box<Integer>();

Diament

W języku Java SE 7 i nowszych można zastąpić argumenty typu wymagane do wywołania konstruktora klasy ogólnej pustym zestawem argumentów typu (< >), o ile kompilator może określić lub wywnioskować argumenty typu z kontekstu. Ta para nawiasów kątowych, < >, jest nieformalnie nazywana diamentem. Na przykład możesz utworzyć wystąpienie Box < Integer > za pomocą następującej instrukcji:

Box<Integer> integerBox = new Box<>();

Aby uzyskać więcej informacji na temat notacji rombu i wnioskowania o typie, zobacz Wnioskowanie o typie.

Wiele parametrów typu

Jak wspomniano wcześniej, klasa ogólna może mieć wiele parametrów typu.Na przykład ogólna klasa OrderedPair, która implementuje ogólny interfejs Pair:

Poniższe instrukcje tworzą dwie instancje klasy OrderedPair:

Kod, nowy OrderedPair < String, Integer >, tworzy instancję K jako ciąg i V jako liczbę całkowitą. Dlatego typami parametrów konstruktora OrderedPair są odpowiednio String i Integer. Ze względu na autoboxing prawidłowe jest przekazywanie String i int do klasy.

Jak wspomniano w The Diamond, ponieważ Kompilator Java może wywnioskować typy K i V na podstawie deklaracji OrderedPair < String, Integer >, te instrukcje można skrócić za pomocą notacji diamentowej:

OrderedPair<String, Integer> p1 = new OrderedPair<>("Even", 8);OrderedPair<String, String> p2 = new OrderedPair<>("hello", "world");

Aby utworzyć interfejs ogólny, postępuj zgodnie z tymi samymi konwencjami, co przy tworzeniu klasy ogólnej.

Typy sparametryzowane

OrderedPair<String, Box<Integer>> p = new OrderedPair<>("primes", new Box<Integer>(...));

Write a Comment

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *