Médio Java
Métodos default e interface funcional
Enunciado
Crie uma interface funcional Operacao com o método int calcular(int a, int b). Adicione um método default int calcularComZero(int a) que usa calcular(a, 0). No main, use lambdas para criar uma soma e uma multiplicação, e chame tanto calcular quanto calcularComZero.
Requisitos
- A interface
Operacaodeve ser anotada com@FunctionalInterfacee ter um único método abstrato. - Deve conter um método
default int calcularComZero(int a)que chamacalcular(a, 0). - O
maindeve criar lambdas para soma e multiplicação e imprimir os resultados decalcularecalcularComZero.
Código inicial
@FunctionalInterface
interface Operacao {
int calcular(int a, int b);
// TODO: adicione o método default calcularComZero
}
public class Main {
public static void main(String[] args) {
// TODO: crie lambdas e teste os métodos
}
}
Saída esperada
Soma 5+3: 8
Soma 5+0: 5
Multiplicacao 5*3: 15
Multiplicacao 5*0: 0
Ver dica
Lembre-se de que o método default pode chamar o método abstrato da própria interface. Para a multiplicação, calcularComZero(5) deve retornar 0.
Mostrar solução
@FunctionalInterface
interface Operacao {
int calcular(int a, int b); // único método abstrato
// Método default que reutiliza o método abstrato
default int calcularComZero(int a) {
return calcular(a, 0);
}
}
public class Main {
public static void main(String[] args) {
// Lambda para soma
Operacao soma = (a, b) -> a + b;
// Lambda para multiplicação
Operacao multiplicacao = (a, b) -> a * b;
System.out.println("Soma 5+3: " + soma.calcular(5, 3));
System.out.println("Soma 5+0: " + soma.calcularComZero(5));
System.out.println("Multiplicacao 5*3: " + multiplicacao.calcular(5, 3));
System.out.println("Multiplicacao 5*0: " + multiplicacao.calcularComZero(5));
}
}
Passo a passo
- A anotação
@FunctionalInterfacegarante que a interface tenha exatamente um método abstrato. Se adicionarmos outro, o compilador reclama. - O método
calcular(int a, int b)é o contrato principal que as lambdas vão implementar. - O método
default int calcularComZero(int a)fornece uma implementação padrão que chamacalcular(a, 0). Classes que implementamOperacaonão precisam redefini-lo. - No
main, criamos duas lambdas:somaemultiplicacao. Cada uma implementa o método abstratocalcular. - Chamamos
calculardiretamente nas lambdas para obter os resultados esperados. - Chamamos
calcularComZero, que usa internamente a lambda correspondente, passando 0 como segundo argumento.
Por que funciona
Interfaces funcionais permitem que lambdas sejam atribuídas a variáveis do tipo da interface. O método default calcularComZero é herdado por qualquer implementação (incluindo lambdas) e pode chamar o método abstrato, que será resolvido dinamicamente para a lambda específica. Isso mostra como métodos default adicionam comportamento sem quebrar implementações existentes.
Erros comuns
- Adicionar outro método abstrato à interface:
int subtrair(int a, int b);faz o compilador acusar que@FunctionalInterfacenão é mais válida. Remova a anotação ou torne o métododefault. - Esquecer a palavra-chave
defaultno método com implementação:int calcularComZero(int a) { ... }não compila, pois métodos de interface sem corpo são abstratos. - Tentar usar uma lambda sem que a interface seja funcional: se houver dois métodos abstratos, a lambda não pode ser usada.
Outra forma de resolver
Poderia usar classes anônimas em vez de lambdas:
Operacao soma = new Operacao() {
@Override
public int calcular(int a, int b) {
return a + b;
}
};
Lambdas são preferíveis por serem mais concisas e legíveis quando a interface é funcional.
Saída esperada
Soma 5+3: 8
Soma 5+0: 5
Multiplicacao 5*3: 15
Multiplicacao 5*0: 0