Desafio Java

Enum com método abstrato e agrupamento com EnumMap

Enunciado

Crie um enum Operacao com SOMA, SUBTRACAO, MULTIPLICACAO e DIVISAO. Cada constante deve implementar um método abstrato double aplicar(double a, double b). No main, use um EnumMap<Operacao, Double> para armazenar o resultado de aplicar cada operação a 10 e 2. Imprima cada operação e seu resultado no formato OPERACAO: resultado.

Requisitos

  • Cada constante do enum deve fornecer sua própria implementação de aplicar.
  • O método aplicar deve ser abstrato no enum.
  • O EnumMap deve ser populado com o resultado de aplicar(10, 2) para cada operação.
  • A impressão deve percorrer Operacao.values() e mostrar nome: resultado.

Código inicial

import java.util.EnumMap;

public class ExercicioEnumAbstrato {
    enum Operacao {
        // TODO: constantes com corpo e método abstrato
    }

    public static void main(String[] args) {
        // TODO: preencher EnumMap e imprimir
    }
}

Saída esperada

SOMA: 12.0
SUBTRACAO: 8.0
MULTIPLICACAO: 20.0
DIVISAO: 5.0
Ver dica

Declare abstract double aplicar(double a, double b); no enum. Cada constante deve ter um corpo { ... } implementando o método. Use EnumMap<Operacao, Double> e put(op, op.aplicar(10, 2)).

Mostrar solução
import java.util.EnumMap;

public class ExercicioEnumAbstrato {
    enum Operacao {
        SOMA {
            @Override
            double aplicar(double a, double b) { return a + b; }
        },
        SUBTRACAO {
            @Override
            double aplicar(double a, double b) { return a - b; }
        },
        MULTIPLICACAO {
            @Override
            double aplicar(double a, double b) { return a * b; }
        },
        DIVISAO {
            @Override
            double aplicar(double a, double b) { return a / b; }
        };

        abstract double aplicar(double a, double b);
    }

    public static void main(String[] args) {
        EnumMap<Operacao, Double> resultados = new EnumMap<>(Operacao.class);

        for (Operacao op : Operacao.values()) {
            resultados.put(op, op.aplicar(10, 2));
        }

        for (Operacao op : Operacao.values()) {
            System.out.println(op + ": " + resultados.get(op));
        }
    }
}

Passo a passo

  1. Declaramos o enum Operacao com quatro constantes, cada uma seguida de um bloco { ... }.
  2. Dentro de cada bloco, sobrescrevemos o método aplicar com a operação específica.
  3. Após as constantes, declaramos o método abstrato abstract double aplicar(double a, double b);.
  4. No main, criamos um EnumMap com chave Operacao e valor Double.
  5. Para cada operação em values(), chamamos op.aplicar(10, 2) e armazenamos no mapa com put.
  6. Em outro loop, percorremos values() e imprimimos op + ": " + resultados.get(op).

Por que funciona

Enums podem ter métodos abstratos, forçando cada constante a fornecer sua própria implementação. Isso é uma forma de polimorfismo sem herança explícita. O EnumMap aproveita o fato de que cada constante tem um índice ordinal, resultando em armazenamento compacto e acesso rápido. A combinação permite associar comportamentos e dados de forma elegante.

Erros comuns

  • Esquecer o ponto e vírgula após a última constante antes do método abstrato: DIVISAO { ... } deve terminar com ;.
  • Declarar o método abstrato como public: em enums, métodos abstratos não podem ser public se a constante os implementa com visibilidade de pacote; o correto é omitir o modificador ou usar protected (mas o padrão é sem modificador).
  • Tentar instanciar o enum: new Operacao() não compila.
  • Usar resultados.get(op) sem ter populado: retorna null; certifique-se de preencher todas as chaves.

Outra forma de resolver

Poderia-se usar um switch dentro de um único método aplicar no enum, sem métodos abstratos:

double aplicar(double a, double b) {
    return switch (this) {
        case SOMA -> a + b;
        case SUBTRACAO -> a - b;
        case MULTIPLICACAO -> a * b;
        case DIVISAO -> a / b;
    };
}

Essa abordagem é preferível quando a lógica é simples e centralizada, mas o método abstrato é melhor para comportamentos complexos e específicos de cada constante.

Saída esperada

SOMA: 12.0
SUBTRACAO: 8.0
MULTIPLICACAO: 20.0
DIVISAO: 5.0