Implementando Interfaces
Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy — lição 35 de 87.
Para usar uma interface, uma classe deve implementá-la usando a palavra-chave implements. A classe então fornece implementações concretas para todos os métodos declarados na interface:
public interface Drawable {
void draw();
}
public class Circle implements Drawable {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a circle with radius " + radius);
}
}Se uma classe implementa uma interface, mas não fornece implementações para todos os seus métodos, o compilador lançará um erro. A anotação @Override é opcional, mas recomendada, pois ajuda a detectar erros.
Assim como acontece com as classes abstratas, você pode usar uma interface como um tipo de referência. Isso permite o polimorfismo, onde diferentes classes que implementam a mesma interface podem ser tratadas de forma uniforme:
Drawable shape1 = new Circle(5.0);
Drawable shape2 = new Rectangle(4.0, 3.0);
shape1.draw(); // Desenhando um círculo com raio 5.0
shape2.draw(); // Desenhando um retângulo 4.0 x 3.0Isso é poderoso porque o código que trabalha com referências Drawable não precisa conhecer o tipo de classe específico. Ele apenas se importa que o objeto possa ser desenhado.
Na próxima aula, você verá como uma única classe pode implementar múltiplas interfaces simultaneamente.
Desafio
FácilVamos construir um sistema de alto-falantes que demonstra como as classes implementam interfaces. Você criará uma interface que define o que qualquer alto-falante pode fazer e, em seguida, construirá dois tipos diferentes de alto-falantes que implementam esse contrato à sua maneira.
Você organizará seu código em quatro arquivos:
Speaker.java: Defina uma interface chamadaSpeakerque declara o que qualquer alto-falante deve ser capaz de fazer. Todo alto-falante deve ter um métodospeak()que retorna uma String—este é o contrato que todas as classes implementadoras devem cumprir.Human.java: Crie uma classe que implemente a interfaceSpeaker. Um Human possui um camponame(String). Inclua um construtor para inicializar o nome e implemente o métodospeak()para retornar:[name] says: Hello everyone!Robot.java: Crie outra classe que implemente a interfaceSpeaker. Um Robot possui um campomodel(String). Inclua um construtor para inicializar o modelo e implemente o métodospeak()para retornar:Robot [model] says: Beep boop!Main.java: Reúna tudo usando polimorfismo baseado em interface. Você receberá duas entradas: um nome humano e um modelo de robô. Crie um Human e um Robot, depois armazene-os em um array de referênciasSpeaker. Percorra o array e imprima o resultado da chamada despeak()em cada alto-falante.
Você receberá duas entradas: o nome do humano (String) e o modelo do robô (String).
Sua saída deve mostrar duas linhas—uma para cada alto-falante. Observe como tanto o Human quanto o Robot podem ser tratados de forma uniforme através da interface Speaker, mesmo que falem de maneiras completamente diferentes!
Folha de consulta
Uma classe usa a palavra-chave implements para implementar uma interface e deve fornecer implementações concretas para todos os métodos declarados na interface:
public interface Drawable {
void draw();
}
public class Circle implements Drawable {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a circle with radius " + radius);
}
}A anotação @Override é opcional, mas recomendada, pois ajuda a capturar erros.
Interfaces podem ser usadas como tipos de referência, permitindo o polimorfismo, onde diferentes classes que implementam a mesma interface podem ser tratadas de forma uniforme:
Drawable shape1 = new Circle(5.0);
Drawable shape2 = new Rectangle(4.0, 3.0);
shape1.draw(); // Desenhando um círculo com raio 5.0
shape2.draw(); // Desenhando um retângulo 4.0 x 3.0Experimente você mesmo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Ler entradas
String humanName = scanner.nextLine();
String robotModel = scanner.nextLine();
// TODO: Criar um objeto Human com o nome fornecido
// TODO: Criar um objeto Robot com o modelo fornecido
// TODO: Criar um array de referências Speaker contendo ambos os objetos
// TODO: Percorrer o array e imprimir o resultado de speak() para cada speaker
}
}
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 Iterator