Menu
Coddy logo textTech

Clases genéricas

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 54 de 87.

Ahora que entiendes por qué los genéricos son útiles, vamos a crear tu propia clase genérica. Una clase genérica declara uno o más parámetros de tipo entre corchetes angulares después del nombre de la clase, que después pueden usarse en toda la clase.

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

T es un parámetro de tipo: un marcador de posición que se reemplaza por un tipo real cuando creas una instancia. Puedes usar cualquier nombre, pero las letras mayúsculas individuales son convencionales: T para Type, E para Element, K para Key, V para Value.

Al instanciar una clase genérica, especificas el tipo real entre corchetes angulares:

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

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

Observa el <> (operador diamante) en el lado derecho: Java infiere el tipo a partir de la declaración. También puedes usar varios parámetros de tipo para clases que necesitan trabajar con más de 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

Desafío

Fácil

Construyamos un sistema de registro de regalos que muestre el poder de las clases genéricas. Crearás un sistema de almacenamiento flexible que puede contener cualquier tipo de artículo de regalo, además de un registro que asocia los nombres de los regalos con sus detalles mediante varios parámetros de tipo.

Organizarás tu código en tres archivos:

  • GiftBox.java: Crea una clase genérica que pueda envolver cualquier tipo de regalo. Tu GiftBox<T> debe tener un campo privado item de tipo T y un campo privado wrapped (booleano) que comience como false. Incluye un constructor que acepte el artículo, un método getItem() que devuelva el artículo, un método wrap() que establezca wrapped en true y un método isWrapped() que devuelva el estado de wrapped. Añade un método getStatus() que devuelva [item] (wrapped) o [item] (unwrapped) según el estado de wrapped.
  • Registry.java: Crea una clase genérica con dos parámetros de tipo que asocie a un destinatario con su regalo. Tu Registry<K, V> debe tener campos privados recipient de tipo K y gift de tipo V. Incluye un constructor que acepte ambos valores, métodos getter getRecipient() y getGift(), y un método getEntry() que devuelva: [recipient] -> [gift]
  • Main.java: ¡Da vida a tu registro de regalos! Recibirás tres entradas: el nombre de un destinatario (String), la descripción de un regalo (String) y el valor de un regalo (un entero que representa dólares).

    Primero, crea un GiftBox<String> que contenga la descripción del regalo. Envuélvelo usando el método wrap() y después imprime su estado.

    A continuación, crea un GiftBox<Integer> que contenga el valor del regalo (que representa el importe de una tarjeta de regalo). No envuelvas este: imprime su estado para mostrar que no está envuelto.

    Por último, crea un Registry<String, String> que asocie el nombre del destinatario con la descripción del regalo e imprime la entrada del registro.

Recibirás tres entradas en este orden: nombre del destinatario, descripción del regalo y valor del regalo (como un entero).

Observa cómo la misma clase GiftBox funciona perfectamente tanto con tipos String como Integer: ¡esa es la belleza de los genéricos! Y la clase Registry demuestra cómo varios parámetros de tipo te permiten crear asociaciones flexibles entre dos tipos cualesquiera.

Pruébalo tú mismo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Leer entradas
        String recipientName = scanner.nextLine();
        String giftDescription = scanner.nextLine();
        int giftValue = scanner.nextInt();
        
        // TODO: Crea un GiftBox<String> que contenga la descripción del regalo
        // TODO: Envuélvelo usando el método wrap()
        // TODO: Imprime su estado usando getStatus()
        
        // TODO: Crea un GiftBox<Integer> que contenga el valor del regalo
        // TODO: No envuelvas este - imprime su estado (debería mostrar unwrapped)
        
        // TODO: Crea un Registry<String, String> emparejando el destinatario con la descripción del regalo
        // TODO: Imprime la entrada del registro usando getEntry()
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Java online