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 vous comprenez pourquoi les génériques sont utiles, créons votre 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 uniques sont conventionnelles : T pour Type, E pour Élément, K pour Clé, V pour Valeur.

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 transtypage nécessaire

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

Remarquez l'<> (opérateur diamant) sur le côté droit — 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 illustre la puissance des classes génériques. Vous allez créer un système de stockage flexible capable de contenir n'importe quel type d'article de cadeau, ainsi qu'un registre qui associe les noms des cadeaux à leurs détails en utilisant plusieurs paramètres de type.

Vous organiserez votre code sur trois fichiers :

  • GiftBox.java : Créez une classe générique capable d'emballer n'importe quel type de cadeau. Votre GiftBox<T> doit avoir un champ privé item de type T et un champ privé wrapped (booléen) qui commence à false. Incluez un constructeur qui accepte l'article, une méthode getItem() qui retourne l'article, une méthode wrap() qui définit wrapped à true, et une méthode isWrapped() qui retourne l'état d'emballage. Ajoutez une méthode getStatus() qui retourne soit [item] (wrapped) soit [item] (unwrapped) selon l'état d'emballage.
  • 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 avoir des champs privés recipient de type K et gift de type V. Incluez un constructeur qui accepte les deux valeurs, des méthodes getter getRecipient() et getGift(), et une méthode getEntry() qui retourne : [recipient] -> [gift]
  • Main.java : Donnez vie à votre registre de cadeaux ! Vous recevrez trois entrées : un nom de destinataire (String), une description de cadeau (String) et une valeur de cadeau (entier représentant des dollars).

    Tout d'abord, créez un GiftBox<String> contenant la description du cadeau. Emballez-le en utilisant la méthode wrap(), puis affichez son statut.

    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 statut pour montrer qu'il n'est pas emballé.

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

Vous recevrez trois entrées dans l'ordre : 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 démontre comment plusieurs paramètres de type vous permettent de créer des associations flexibles entre n'importe quels deux types.

Aide-mémoire

Une classe générique déclare un ou plusieurs paramètres de type entre chevrons après le nom de la classe, lesquels peuvent ê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é remplacé par un type réel lors de la création d'une instance. Les conventions courantes utilisent des lettres majuscules uniques : T pour Type, E pour Element, K pour Key, V pour Value.

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

Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String value = stringBox.get();  // No casting needed

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

L'opérateur <> (diamond operator) permet à Java d'inférer le type à partir de la déclaration.

Utilisez plusieurs paramètres de type pour les classes qui travaillent 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);

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'emballer 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 emballer celui-ci - afficher son statut (devrait indiquer non emballé)
        
        // 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