Metody generyczne
Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 55 z 87.
Klasy generyczne sprawiają, że całe klasy mogą działać z różnymi typami, ale czasami potrzebujesz, aby tylko jedna metoda była generyczna. Metoda generyczna deklaruje własny parametr typu, niezależny od parametrów generycznych klasy.
Parametr typu pojawia się przed typem zwracanym w sygnaturze metody:
public class Utility {
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.println(element);
}
}
}
String[] names = {"Alice", "Bob"};
Integer[] numbers = {1, 2, 3};
Utility.printArray(names); // Działa z String[]
Utility.printArray(numbers); // Działa z Integer[]Zwróć uwagę na <T> umieszczone między modyfikatorami a typem zwracanym. Deklaruje ono T jako parametr typu dla tej konkretnej metody. Kompilator wnioskuje rzeczywisty typ na podstawie przekazanych argumentów.
Metody generyczne mogą również zwracać typ generyczny:
public static <T> T getFirst(T[] array) {
if (array.length > 0) {
return array[0];
}
return null;
}
String first = getFirst(new String[]{"a", "b"}); // Zwraca "a"W razie potrzeby możesz używać wielu parametrów typu:
public static <K, V> void printPair(K key, V value) {
System.out.println(key + ": " + value);
}
printPair("Age", 25); // String i Integer
printPair(1, "First"); // Integer i StringMetody generyczne są szczególnie przydatne w klasach narzędziowych, w których potrzebujesz elastycznych, wielokrotnego użytku operacji bez tworzenia klasy generycznej.
Wyzwanie
ŁatwyStwórzmy zestaw narzędzi, który pokaże elastyczność metod generycznych. Utworzysz klasę z metodami wielokrotnego użytku, które działają z dowolnym typem, demonstrując, że metody generyczne mogą istnieć niezależnie od klas generycznych.
Rozmieścisz swój kod w dwóch plikach:
ArrayUtils.java: Utwórz klasę narzędziową zawierającą metody generyczne do pracy z tablicami. Twoja klasa powinna mieć trzy statyczne metody generyczne:getLast— metoda generyczna, która przyjmuje tablicę typuTi zwraca ostatni element. Jeśli tablica jest pusta, zwróćnull.swap— metoda generyczna, która przyjmuje tablicę typuTi dwa indeksy całkowite, a następnie zamienia miejscami elementy znajdujące się pod tymi indeksami. Ta metoda niczego nie zwraca.printWithLabel— metoda generyczna z dwoma parametrami typuKiV. Przyjmuje etykietę typuKi wartość typuV, a następnie wyświetla je w formacie:[label]: [value]Main.java: Wykorzystaj swoje metody generyczne! Otrzymasz cztery dane wejściowe: dwa słowa (typu String) i dwie liczby (typu integer).Najpierw utwórz tablicę
String[]zawierającą oba słowa. UżyjgetLast, aby pobrać ostatni element i wyświetl:Last word: [result]Następnie utwórz tablicę
Integer[]zawierającą obie liczby. Wywołajswap, aby zamienić miejscami elementy o indeksach 0 i 1, a następnie wyświetl:After swap: [first], [second]Na koniec zademonstruj działanie metody generycznej z dwoma parametrami, wywołując
printWithLabeldwukrotnie:- Raz, używając pierwszego słowa jako etykiety, a pierwszej liczby jako wartości
- Raz, używając pierwszej liczby jako etykiety, a drugiego słowa jako wartości
Otrzymasz cztery dane wejściowe w następującej kolejności: pierwsze słowo, drugie słowo, pierwsza liczba, druga liczba.
Zwróć uwagę, że każda metoda deklaruje własne parametry typu za pomocą <T> lub <K, V> przed typem zwracanym. Kompilator wnioskuje rzeczywiste typy na podstawie przekazanych argumentów — nie musisz podawać ich jawnie podczas wywoływania metod!
Spróbuj swoich sił
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Wczytaj dane wejściowe
String firstWord = scanner.nextLine();
String secondWord = scanner.nextLine();
int firstNumber = scanner.nextInt();
int secondNumber = scanner.nextInt();
// TODO: Utwórz tablicę String[] zawierającą oba słowa
// TODO: Użyj ArrayUtils.getLast, aby pobrać ostatni element
// Wypisz: "Last word: [result]"
// TODO: Utwórz tablicę Integer[] zawierającą obie liczby
// TODO: Wywołaj ArrayUtils.swap, aby zamienić miejscami elementy o indeksach 0 i 1
// Wypisz: "After swap: [first], [second]"
// TODO: Wywołaj ArrayUtils.printWithLabel, przekazując firstWord jako etykietę i firstNumber jako wartość
// TODO: Wywołaj ArrayUtils.printWithLabel, przekazując firstNumber jako etykietę i secondWord jako wartość
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneWprowadzenie do programowania obiektowegoKlasy a obiektySłowo kluczowe thisMetodyPola (atrybuty)Metoda konstruktoraPrzeciążanie konstruktoraPodsumowanie — prosty kalkulator4Dziedziczenie
Podstawy dziedziczenia (extends)Słowo kluczowe superPrzesłanianie metod (@Override)Łańcuch wywołań konstruktorówKlasa ObjectDziedziczenie jedno- i wielopoziomoweDlaczego Java nie obsługuje wielodziedziczenia klasPodsumowanie – hierarchia pracowników7Metody specjalne i klasa Object
Metoda toString()equals() i hashCode()Metoda clone()compareTo() i ComparableInterfejs ComparatorPodsumowanie — własne sortowanie10Obsługa wyjątków w programowaniu obiektowym
Hierarchia klas wyjątkówWłasne wyjątkiBłędy sprawdzane a niesprawdzaneWzorzec try-with-resourcesPodsumowanie – zweryfikowany użytkownik2Modyfikatory dostępu i enkapsulacja
Przegląd poziomów dostępuMetody pobierające i ustawiająceUkrywanie informacjiSłowo kluczowe finalPodsumowanie — menedżer kont bankowych5Polimorfizm
Podstawy przeciążania metodPrzesłanianie metod (w czasie wykonywania)Rzutowanie w górę i w dółOperator instanceofKlasy i metody abstrakcyjnePowtórka — kalkulator figur8Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieAgregacja a kompozycjaKlasy wewnętrzne, zagnieżdżone i anonimoweEnumy i metody enumówRekordy (Java 16+)Klasy zapieczętowane (Java 17+)11Wzorce projektowe — część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec BuilderWzorzec ObserverWzorzec Strategy3Właściwości klas i składowe statyczne
Zmienne instancji a zmienne statyczneMetody statyczneBloki statyczneStałe (static final)Powtórka – Counter i Utility6Interfejsy i klasy abstrakcyjne
Wprowadzenie do interfejsówImplementowanie interfejsówImplementacja wielu interfejsówMetody domyślne i statyczne w interfejsieKlasy abstrakcyjne a interfejsyInterfejsy funkcyjnePodsumowanie — system płatnościPoćwicz samodzielnie: Kompilator Java online