Default e Static em Interfaces
Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy. Lição 37 de 87.
Originalmente, as interfaces só podiam conter métodos abstratos sem implementação. A partir do Java 8, as interfaces passaram a poder incluir métodos padrão e métodos estáticos, tornando-as mais flexíveis.
Um método padrão fornece uma implementação diretamente na interface usando a palavra-chave default. As classes que implementam a interface herdam esse comportamento automaticamente, mas podem substituí-lo se necessário:
public interface Drawable {
void draw();
default void display() {
System.out.println("Displaying on screen...");
draw();
}
}Qualquer classe que implemente Drawable obtém o método display() gratuitamente. Isso é particularmente útil para adicionar novos métodos a interfaces existentes sem quebrar classes que já os implementam.
Métodos estáticos em interfaces funcionam como métodos estáticos em classes. Eles pertencem à própria interface e são chamados usando o nome da interface:
public interface MathOperations {
static int add(int a, int b) {
return a + b;
}
}
// Uso
int result = MathOperations.add(5, 3);Métodos estáticos de interface não podem ser sobrescritos e não são herdados pelas classes que os implementam. Eles são úteis para métodos utilitários relacionados à finalidade da interface.
Se uma classe implementa duas interfaces com a mesma assinatura de método padrão, a classe deve substituir esse método para resolver o conflito.
Desafio
FácilVamos criar um sistema de mensagens que demonstra tanto métodos padrão quanto métodos estáticos em interfaces. Você criará uma interface com funcionalidade integrada que as classes que a implementarem poderão usar diretamente ou personalizar conforme necessário.
Você organizará seu código em quatro arquivos:
Messenger.java: Defina uma interface que represente qualquer serviço de mensagens. Ela deve declarar um método abstratosendMessage(String message)que retorna void. Adicione um método padrão chamadosendWithTimestamp(String message)que imprima:[TIMESTAMP]seguido da chamada desendMessage(message). Inclua também um método estático chamadoformatMessage(String message)que retorne a mensagem convertida para letras maiúsculas.EmailMessenger.java: Crie uma classe que implementeMessenger. Ela terá um camporecipient(String). Inclua um construtor para inicializar o destinatário. ImplementesendMessage()para imprimir:Email to [recipient]: [message]. Essa classe usa o método padrãosendWithTimestamp()como está.SMSMessenger.java: Crie outra classe que implementeMessenger. Ela terá um campophoneNumber(String). Inclua um construtor para inicializar o número de telefone. ImplementesendMessage()para imprimir:SMS to [phoneNumber]: [message]. Substitua o método padrãosendWithTimestamp()para imprimir:[URGENT]seguido da chamada desendMessage(message), em vez de usar o comportamento padrão de registro de data e hora.Main.java: Reúna tudo para demonstrar os métodos padrão e estático de interfaces. Você receberá três entradas: um destinatário de e-mail, um número de telefone e uma mensagem. Primeiro, use o método estáticoMessenger.formatMessage()para formatar a mensagem e armazená-la. Em seguida, crie um EmailMessenger e um SMSMessenger. Para cada mensageiro, chamesendWithTimestamp()com a mensagem formatada: observe como o EmailMessenger usa a implementação padrão, enquanto o SMSMessenger usa sua versão substituída.
Você receberá três entradas: o destinatário do e-mail (String), o número de telefone (String) e a mensagem (String).
Sua saída deve mostrar quatro linhas ao todo: duas para cada mensageiro: uma linha de prefixo ([TIMESTAMP] ou [URGENT]) seguida pela linha da mensagem. O EmailMessenger mostrará o prefixo de registro de data e hora padrão, enquanto o SMSMessenger mostrará seu prefixo urgente personalizado. Ambos usarão a mensagem formatada estaticamente (em letras maiúsculas)!
Experimente você mesmo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Ler entradas
String emailRecipient = scanner.nextLine();
String phoneNumber = scanner.nextLine();
String message = scanner.nextLine();
// TODO: Use Messenger.formatMessage() para formatar a mensagem e armazená-la
// TODO: Crie um EmailMessenger com o destinatário do e-mail
// TODO: Crie um SMSMessenger com o número de telefone
// TODO: Chame sendWithTimestamp() no EmailMessenger com a mensagem formatada
// TODO: Chame sendWithTimestamp() no SMSMessenger com a mensagem formatada
}
}
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
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave thisMétodosCampos (Atributos)Método ConstrutorSobrecarga de ConstrutorRecapitulação - Calculadora Simples4Herança
Herança Básica (extends)A Palavra-chave superSobrescrita de Método (@Override)Encadeamento de ConstrutoresA Classe ObjectHerança Simples e MultinívelPor que não há Herança Múltipla de ClassesRecapitulação - Hierarquia de Funcionários7Métodos Especiais e a Classe Object
Método toString()equals() e hashCode()Método clone()compareTo() e ComparableInterface ComparatorRecapitulação - Ordenação Personalizada2Modificadores de Acesso e Encapsulamento
Visão Geral dos Níveis de AcessoMétodos Getter e SetterOcultação de InformaçõesA Palavra-chave finalRecapitulação - Gerenciador de Conta Bancária5Polimorfismo
Fundamentos de Sobrecarga de MétodosSobrescrita de Métodos (Tempo de Execução)Upcasting e DowncastingO Operador instanceofClasses e Métodos AbstratosRecapitulação - Calculadora de Formas8Conceitos Avançados de OOP
Composição vs HerançaAgregação vs ComposiçãoClasses Internas, Aninhadas e AnônimasEnums e Métodos de EnumRecords (Java 16+)Classes Seladas (Java 17+)11Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão BuilderPadrão ObserverPadrão Strategy3Propriedades de Classe e Membros Estáticos
Variáveis de Instância vs EstáticasMétodos EstáticosBlocos EstáticosConstantes (static final)Recapitulação - Contador e Utilitário6Interfaces e Classes Abstratas
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesDefault e Static em InterfacesClasses Abstratas vs InterfacesInterfaces FuncionaisRecapitulação - Sistema de Pagamento9Generics
Introdução a GenericsClasses GenéricasMétodos GenéricosParâmetros de Tipos DelimitadosWildcards (?, extends, super)Recapitulação - Container Genérico12Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão IteratorPratique por conta própria: Compilador de Java online