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 Tipo, E para Elemento, K para Chave, V para Valor.

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();  // Não é necessário casting

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 do presente (String) e um valor do 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.

    Depois, 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.

    Por fim, 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 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.

Experimente você mesmo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Lê as entradas
        String recipientName = scanner.nextLine();
        String giftDescription = scanner.nextLine();
        int giftValue = scanner.nextInt();
        
        // TODO: Crie um GiftBox<String> contendo a descrição do presente
        // TODO: Embrulhe-o usando o método wrap()
        // TODO: Imprima seu status usando getStatus()
        
        // TODO: Crie um GiftBox<Integer> contendo o valor do presente
        // TODO: Não embrulhe este - imprima seu status (deve mostrar unwrapped)
        
        // TODO: Crie um Registry<String, String> associando o destinatário com a descrição do presente
        // TODO: Imprima 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