Interfaces definem as possibilidades de interação de uma classe com o mundo externo por meio de seus métodos públicos. No dia a dia, lidamos constantemente com interfaces: por exemplo, ligamos uma televisão ao pressionar um botão "ON/OFF", ajustamos o volume ou mudamos o canal — tudo isso sem conhecer os detalhes internos da eletrônica envolvida. Os botões formam a interface entre nós e os circuitos que fazem o aparelho funcionar.
De forma semelhante, em Java, interfaces especificam o que deve ser feito, mas não como. Uma interface em Java é, geralmente, um conjunto de métodos sem corpo, que atuam como um contrato que as classes devem cumprir. Por exemplo, a interface de uma televisão poderia ser:
interface Televisao {
void setLigada(boolean estado);
void setVolume(int valor);
void setCanal(int numero);
}
Qualquer classe que implemente essa interface será obrigada a fornecer suas próprias implementações para esses métodos, o que permite que diferentes fabricantes desenvolvam televisores com comportamentos internos distintos, mas com a mesma forma de interação.
Interfaces são semelhantes a classes, mas com diferenças importantes. Elas podem conter:
static final
)default
)Interfaces são amplamente utilizadas em desenvolvimento de software para garantir que diferentes partes de um sistema, muitas vezes desenvolvidas por equipes distintas, possam se comunicar corretamente. Elas estabelecem um contrato formal que as classes devem seguir, promovendo a separação entre a definição e a implementação dos comportamentos.
Uma das maiores vantagens das interfaces é a herança múltipla. Java não permite herança múltipla de classes (para evitar ambiguidades de implementação), mas permite que uma classe implemente múltiplas interfaces. Isso permite que uma classe herde comportamentos (no sentido de métodos que ela deve implementar) de diversas fontes, sem herdar código diretamente.
Considere o exemplo abaixo, com duas interfaces (Animal
e Mamifero
) e três classes que as implementam:
public interface Animal {
void emitirSom();
}
public interface Mamifero {
void amamentar();
}
public class Cachorro implements Animal, Mamifero {
@Override
public void emitirSom() {
System.out.println("*Late*");
}
@Override
public void amamentar() {
System.out.println("A cadela amamenta seus filhotes");
}
}
public class Gato implements Animal, Mamifero {
@Override
public void emitirSom() {
System.out.println("*Mia*");
}
@Override
public void amamentar() {
System.out.println("A gata amamenta seus filhotes");
}
}
public class Boi implements Animal, Mamifero {
@Override
public void emitirSom() {
System.out.println("*Muge*");
}
@Override
public void amamentar() {
System.out.println("A vaca amamenta seus filhotes");
}
}
Essas classes fornecem implementações específicas para os métodos definidos nas interfaces. A interface age como um guia para garantir que todas as classes compartilhem um conjunto comum de comportamentos, ainda que cada uma os implemente de forma única.
A linguagem Java possui diversas interfaces integradas em sua API, que são amplamente utilizadas:
ArrayList
, LinkedList
.HashSet
, TreeSet
.HashMap
, TreeMap
.compareTo
.