Classi generiche
Fa parte della sezione Programmazione orientata agli oggetti del percorso Java di Coddy. Lezione 54 di 87.
Ora che hai capito perché i generics sono utili, creiamo la tua classe generica. Una classe generica dichiara uno o più parametri di tipo tra parentesi angolari dopo il nome della classe, che possono poi essere utilizzati in tutta la classe.
class Box<T> {
private T content;
public void set(T content) {
this.content = content;
}
public T get() {
return content;
}
}T è un parametro di tipo: un segnaposto che viene sostituito con un tipo effettivo quando crei un'istanza. Puoi usare qualsiasi nome, ma per convenzione si usano singole lettere maiuscole: T per Type, E per Element, K per Key, V per Value.
Quando istanzi una classe generica, specifichi il tipo effettivo tra parentesi angolari:
Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String value = stringBox.get(); // Non è necessaria alcuna conversione di tipo
Box<Integer> intBox = new Box<>();
intBox.set(42);
Integer num = intBox.get();Nota <> (operatore diamante) sul lato destro: Java deduce il tipo dalla dichiarazione. Puoi anche usare più parametri di tipo per le classi che devono funzionare con più di un tipo:
class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() { return key; }
public V getValue() { return value; }
}
Pair<String, Integer> pair = new Pair<>("age", 25);Sfida
FacileCostruiamo un sistema di registrazione dei regali che mostri la potenza delle classi generiche. Creerai un sistema di archiviazione flessibile, in grado di contenere qualsiasi tipo di regalo, oltre a un registro che abbina i nomi dei regali ai relativi dettagli usando più parametri di tipo.
Organizzerai il codice in tre file:
GiftBox.java: crea una classe generica in grado di incartare qualsiasi tipo di regalo. La tuaGiftBox<T>dovrebbe avere un campo privatoitemdi tipoTe un campo privatowrapped(boolean) che inizialmente valefalse. Includi un costruttore che accetta l'elemento, un metodogetItem()che restituisce l'elemento, un metodowrap()che imposta wrapped su true e un metodoisWrapped()che restituisce lo stato dell'incarto. Aggiungi un metodogetStatus()che restituisce[item] (wrapped)oppure[item] (unwrapped)a seconda dello stato dell'incarto.Registry.java: crea una classe generica con due parametri di tipo che abbina un destinatario al suo regalo. La tuaRegistry<K, V>dovrebbe avere i campi privatirecipientdi tipoKegiftdi tipoV. Includi un costruttore che accetta entrambi i valori, i metodi gettergetRecipient()egetGift()e un metodogetEntry()che restituisce:[recipient] -> [gift]Main.java: dai vita al tuo registro dei regali! Riceverai tre input: il nome del destinatario (String), la descrizione del regalo (String) e il valore del regalo (intero che rappresenta i dollari).Per prima cosa, crea un
GiftBox<String>che contenga la descrizione del regalo. Incartalo usando il metodowrap(), poi stampa il suo stato.Quindi, crea un
GiftBox<Integer>che contenga il valore del regalo (che rappresenta l'importo di una carta regalo). Non incartarlo: stampa il suo stato per mostrare che non è incartato.Infine, crea un
Registry<String, String>che abbini il nome del destinatario alla descrizione del regalo e stampa la voce del registro.
Riceverai tre input in quest'ordine: nome del destinatario, descrizione del regalo e valore del regalo (come intero).
Nota come la stessa classe GiftBox funzioni senza problemi sia con i tipi String sia con i tipi Integer: questa è la bellezza dei generici! E la classe Registry mostra come più parametri di tipo permettano di creare abbinamenti flessibili tra due tipi qualsiasi.
Provalo tu
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Leggi gli input
String recipientName = scanner.nextLine();
String giftDescription = scanner.nextLine();
int giftValue = scanner.nextInt();
// TODO: Crea un GiftBox<String> contenente la descrizione del regalo
// TODO: Confezionalo usando il metodo wrap()
// TODO: Stampa il suo stato usando getStatus()
// TODO: Crea un GiftBox<Integer> contenente il valore del regalo
// TODO: Non confezionare questo regalo - stampa il suo stato (dovrebbe risultare non confezionato)
// TODO: Crea un Registry<String, String> che associ il destinatario alla descrizione del regalo
// TODO: Stampa la voce del registro usando getEntry()
}
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione a oggetti
File esterniIntroduzione alla programmazione a oggettiClassi e oggettiLa parola chiave thisMetodiCampi (attributi)Metodo costruttoreSovraccarico dei costruttoriRipasso - Calcolatrice semplice4Ereditarietà
Ereditarietà di base (extends)La parola chiave superSovrascrittura dei metodi (@Override)Concatenamento dei costruttoriLa classe ObjectEreditarietà singola e multilivelloPerché non esiste l'ereditarietà multipla delle classiRiepilogo: gerarchia dei dipendenti7Metodi speciali e classe Object
Metodo toString()equals() e hashCode()Metodo clone()compareTo() e ComparableInterfaccia ComparatorRiepilogo - Ordinamento personalizzato2Modificatori di accesso e incapsulamento
Panoramica dei livelli di accessoMetodi getter e setterNascondimento delle informazioniLa parola chiave finalRiepilogo - Gestore di conti bancari5Polimorfismo
Nozioni di base sull'overloading dei metodiOverride dei metodi (a runtime)Upcasting e downcastingL'operatore instanceofClassi e metodi astrattiRiepilogo - Calcolatore di forme8Concetti avanzati di OOP
Composizione vs ereditarietàAggregazione vs composizioneClassi interne, annidate e anonimeEnum e metodi degli EnumRecord (Java 16+)Classi sealed (Java 17+)11Modelli di progettazione Parte 1
Introduzione ai modelli di progettazionePattern SingletonPattern FactoryPattern BuilderPattern ObserverPattern Strategy3Proprietà di classe e membri statici
Variabili di istanza e staticheMetodi staticiBlocchi staticiCostanti (static final)Riepilogo - Contatore e utility6Interfacce e classi astratte
Introduzione alle interfacceImplementazione delle interfacceImplementazione di più interfacceMetodi default e static nelle interfacceClassi astratte e interfacce a confrontoInterfacce funzionaliRiepilogo: sistema di pagamento9Tipi generici
Introduzione ai tipi genericiClassi genericheMetodi genericiParametri di tipo con limitiCaratteri jolly (?, extends, super)Riepilogo - Contenitore generico12Modelli di progettazione – Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositePattern IteratorEsercitati da solo: Compilatore Java online