Menu
Coddy logo textTech

Classes Genéricas

Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy — lição 54 de 87.

Agora que você entende por que os genéricos são úteis, vamos criar sua própria classe genérica. Uma classe genérica declara um ou mais parâmetros de tipo entre colchetes angulares após o nome da classe, que podem então ser usados em toda a classe.

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

O T é um parâmetro de tipo — um marcador de posição que é substituído por um tipo real quando você cria uma instância. Você pode usar qualquer nome, mas letras maiúsculas únicas são convencionais: T para Type, E para Element, K para Key, V para Value.

Ao instanciar uma classe genérica, você especifica o tipo real entre colchetes angulares:

Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String value = stringBox.get();  // Nenhum casting necessário

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

Observe o <> (operador diamante) no lado direito — o Java infere o tipo a partir da declaração. Você também pode usar múltiplos parâmetros de tipo para classes que precisam trabalhar com mais de um 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

Desafio

Fácil

Vamos construir um sistema de registro de presentes que demonstra o poder das classes genéricas. Você criará um sistema de armazenamento flexível que pode conter qualquer tipo de item de presente, além de um registro que associa nomes de presentes com seus detalhes usando múltiplos parâmetros de tipo.

Você organizará seu código em três arquivos:

  • GiftBox.java: Crie uma classe genérica que possa embrulhar qualquer tipo de presente. Sua GiftBox<T> deve ter um campo privado item do tipo T e um campo privado wrapped (boolean) que começa como false. Inclua um construtor que aceite o item, um método getItem() que retorne o item, um método wrap() que defina wrapped como true, e um método isWrapped() que retorne o status de embrulhado. Adicione um método getStatus() que retorne [item] (wrapped) ou [item] (unwrapped) dependendo do estado de embrulho.
  • Registry.java: Crie uma classe genérica com dois parâmetros de tipo que associa um destinatário ao seu presente. Sua Registry<K, V> deve ter campos privados recipient do tipo K e gift do tipo V. Inclua um construtor que aceite ambos os valores, métodos getter getRecipient() e getGift(), e um método getEntry() que retorne: [recipient] -> [gift]
  • Main.java: Dê vida ao seu registro de presentes! Você receberá três entradas: um nome de destinatário (String), uma descrição de presente (String) e um valor de presente (inteiro representando dólares).

    Primeiro, crie uma GiftBox<String> contendo a descrição do presente. Embrulhe-a usando o método wrap() e, em seguida, imprima seu status.

    Em seguida, crie uma GiftBox<Integer> contendo o valor do presente (representando o valor de um cartão-presente). Não embrulhe esta — imprima seu status para mostrar que está desembrulhada.

    Finalmente, crie uma Registry<String, String> associando o nome do destinatário com a descrição do presente e imprima a entrada do registro.

Você receberá três entradas em ordem: nome do destinatário, descrição do presente e valor do presente (como um número inteiro).

Observe como a mesma classe GiftBox funciona perfeitamente com os tipos String e Integer — essa é a beleza dos genéricos! E a classe Registry demonstra como múltiplos parâmetros de tipo permitem criar associações flexíveis entre quaisquer dois tipos.

Folha de consulta

Uma classe genérica declara um ou mais parâmetros de tipo entre colchetes angulares após o nome da classe, que podem ser usados em toda a classe:

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

O T é um parâmetro de tipo — um marcador de posição substituído por um tipo real ao criar uma instância. Convenções comuns usam letras maiúsculas únicas: T para Type (Tipo), E para Element (Elemento), K para Key (Chave), V para Value (Valor).

Ao instanciar uma classe genérica, especifique o tipo real entre colchetes angulares:

Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String value = stringBox.get();  // Nenhuma conversão necessária

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

O <> (operador diamante) permite que o Java infira o tipo a partir da declaração.

Use múltiplos parâmetros de tipo para classes que trabalham com mais de um 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);

Experimente você mesmo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Ler as entradas
        String recipientName = scanner.nextLine();
        String giftDescription = scanner.nextLine();
        int giftValue = scanner.nextInt();
        
        // TODO: Criar uma GiftBox<String> contendo a gift description
        // TODO: Embrulhá-la usando o método wrap()
        // TODO: Imprimir seu status usando getStatus()
        
        // TODO: Criar uma GiftBox<Integer> contendo o gift value
        // TODO: Não embrulhe esta - imprima seu status (deve mostrar unwrapped)
        
        // TODO: Criar um Registry<String, String> pareando recipient com gift description
        // TODO: Imprimir a entrada do registro usando getEntry()
    }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos