Menu
Coddy logo textTech

Classes génériques

Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy. Leçon 54 sur 87.

Maintenant que tu comprends pourquoi les génériques sont utiles, créons ta propre classe générique. Une classe générique déclare un ou plusieurs paramètres de type entre chevrons après le nom de la classe, qui peuvent ensuite être utilisés dans toute la classe.

class Box<T> {
    private T content;
    
    public void set(T content) {
        this.content = content;
    }
    
    public T get() {
        return content;
    }
}

Le T est un paramètre de type : un espace réservé qui est remplacé par un type réel lorsque vous créez une instance. Vous pouvez utiliser n’importe quel nom, mais les lettres majuscules seules sont conventionnelles : T pour Type, E pour Element, K pour Key, V pour Value.

Lors de l’instanciation d’une classe générique, vous spécifiez le type réel entre chevrons :

Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String value = stringBox.get();  // Aucun cast nécessaire

Box<Integer> intBox = new Box<>();
intBox.set(42);
Integer num = intBox.get();

Remarquez l’opérateur <> (opérateur diamant) à droite : Java déduit le type à partir de la déclaration. Vous pouvez également utiliser plusieurs paramètres de type pour les classes qui doivent fonctionner avec plus d’un type :

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

Défi

Facile

Construisons un système de registre de cadeaux qui met en valeur la puissance des classes génériques. Vous allez créer un système de stockage flexible capable de contenir n’importe quel type de cadeau, ainsi qu’un registre qui associe les noms des destinataires à leurs cadeaux à l’aide de plusieurs paramètres de type.

Vous allez organiser votre code dans trois fichiers :

  • GiftBox.java : créez une classe générique capable d’emballer n’importe quel type de cadeau. Votre GiftBox<T> doit posséder un champ privé item de type T et un champ privé wrapped (boolean) initialisé à false. Ajoutez un constructeur qui accepte l’élément, une méthode getItem() qui renvoie l’élément, une méthode wrap() qui définit wrapped sur true, ainsi qu’une méthode isWrapped() qui renvoie l’état de wrapped. Ajoutez une méthode getStatus() qui renvoie soit [item] (wrapped), soit [item] (unwrapped) selon l’état de wrapped.
  • Registry.java : créez une classe générique avec deux paramètres de type qui associe un destinataire à son cadeau. Votre Registry<K, V> doit posséder des champs privés recipient de type K et gift de type V. Ajoutez un constructeur qui accepte les deux valeurs, les méthodes d’accès getRecipient() et getGift(), ainsi qu’une méthode getEntry() qui renvoie : [recipient] -> [gift]
  • Main.java : donnez vie à votre registre de cadeaux ! Vous recevrez trois entrées : le nom d’un destinataire (String), la description d’un cadeau (String) et la valeur d’un cadeau (entier représentant des dollars).

    Commencez par créer un GiftBox<String> contenant la description du cadeau. Emballez-le à l’aide de la méthode wrap(), puis affichez son état.

    Ensuite, créez un GiftBox<Integer> contenant la valeur du cadeau (représentant le montant d’une carte-cadeau). N’emballez pas celui-ci : affichez son état pour montrer qu’il n’est pas emballé.

    Enfin, créez un Registry<String, String> associant le nom du destinataire à la description du cadeau, puis affichez l’entrée du registre.

Vous recevrez trois entrées dans l’ordre suivant : le nom du destinataire, la description du cadeau et la valeur du cadeau (sous forme d’entier).

Remarquez comment la même classe GiftBox fonctionne parfaitement avec les types String et Integer : c’est toute la beauté des génériques ! Et la classe Registry montre comment plusieurs paramètres de type vous permettent de créer des associations flexibles entre deux types quelconques.

Essayez vous-même

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Lire les entrées
        String recipientName = scanner.nextLine();
        String giftDescription = scanner.nextLine();
        int giftValue = scanner.nextInt();
        
        // TODO: Créer un GiftBox<String> contenant la description du cadeau
        // TODO: L'envelopper en utilisant la méthode wrap()
        // TODO: Afficher son statut en utilisant getStatus()
        
        // TODO: Créer un GiftBox<Integer> contenant la valeur du cadeau
        // TODO: Ne pas envelopper celui-ci - afficher son statut (devrait montrer non enveloppé)
        
        // TODO: Créer un Registry<String, String> associant le destinataire à la description du cadeau
        // TODO: Afficher l'entrée du registre en utilisant getEntry()
    }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur Java en ligne