Lições do módulo (1/2)
Interfaces
Embora as classes abstratas possam conter código parcialmente implementado e campos de instância, interfaces em Java são contratos de comportamento puro. Uma interface define o que uma classe deve ser capaz de fazer, mas não como ela o faz.
Isto permite uma dissociação completa entre a definição das operações e a sua implementação real.
Definindo uma interface (interface)
Usamos a palavra-chave interface. Todos os métodos declarados em uma interface são implicitamente public e abstract (não há necessidade de especificá-los):
interface Drivable {
void startEngine();
void stopEngine();
}Implementando uma interface (implements)
Uma classe implementa uma interface usando a palavra-chave implements e é necessária para fornecer a implementação (com um corpo) para todos os métodos definidos:
class Motorcycle implements Drivable {
@Override
public void startEngine() {
System.out.println("Rombo del motore acceso!");
}
@Override
public void stopEngine() {
System.out.println("Motore spento.");
}
}Vantagens das Interfaces
- Herança Múltipla: Em Java, uma classe pode estender apenas uma classe pai (herança única), mas pode implementar múltiplas interfaces ao mesmo tempo.
Java
class HybridCar implements Drivable, Chargeable { ... } - Desacoplamento: Você pode definir variáveis usando o tipo de interface. Qualquer objeto que implemente essa interface pode ser atribuído a tal variável.
Java
Drivable vehicle = new Motorcycle(); vehicle.startEngine();
Constantes em Interfaces
Nas interfaces é possível declarar campos. Esses campos são implicitamente public static final (ou seja, constantes de classe), mesmo se você não especificar esses modificadores. Consequentemente, eles devem ser inicializados imediatamente após a declaração:
interface PhysicsConstants {
double GRAVITY = 9.81; // Implicitly public static final
}Métodos padrão (default)
A partir do Java 8, é possível definir métodos com implementação padrão dentro de uma interface usando a palavra-chave default. Esses métodos não forçam as classes de implementação a substituí-los, fornecendo um comportamento alternativo:
interface Logger {
void log(String message);
// Default method with a body
default void logError(String message) {
log("ERROR: " + message);
}
}Experimente você mesmo
Crie uma interface Flyable com um método void fly(). Em seguida, implemente uma classe Bird que implemente Flyable e imprima Flying na tela.
Mostrar dica
Em Flyable, escreva `void fly();`. Na classe Bird, implemente o método marcando-o com `@Override public void fly() { System.out.println('Flying'); }`.
Solução disponível após 3 tentativas
Defina uma interface Drawable com um método void draw(). Em seguida, implemente uma classe Rectangle que implemente Drawable e imprima Drawing Rectangle.
Mostrar dica
Defina `void draw();` na interface. Em Retângulo, use `@Override public void draw() { System.out.println('Drawing Rectangle'); }`.
Solução disponível após 3 tentativas
Conclua a interface Swimmable definindo o método void swim(). Em seguida, complete a classe Duck para que ela implemente Flyable e Swimmable, imprimindo Flying no método fly() e Swimming no método swim().
Mostrar dica
Declare `void swim();` dentro de Swimmable. Declare `class Duck implements Flyable, Swimmable` e implemente ambos os métodos imprimindo as strings solicitadas.
Solução disponível após 3 tentativas