Menu
Coddy logo textTech

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);
challenge icon

Sfida

Facile

Costruiamo 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 tua GiftBox<T> dovrebbe avere un campo privato item di tipo T e un campo privato wrapped (boolean) che inizialmente vale false. Includi un costruttore che accetta l'elemento, un metodo getItem() che restituisce l'elemento, un metodo wrap() che imposta wrapped su true e un metodo isWrapped() che restituisce lo stato dell'incarto. Aggiungi un metodo getStatus() 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 tua Registry<K, V> dovrebbe avere i campi privati recipient di tipo K e gift di tipo V. Includi un costruttore che accetta entrambi i valori, i metodi getter getRecipient() e getGift() e un metodo getEntry() 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 metodo wrap(), 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()
    }
}
quiz iconMettiti alla prova

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

Esercitati da solo: Compilatore Java online