Depois de aprender sobre herança, encapsulamento, agregação e composição, chegamos a um dos conceitos mais importantes da Programação Orientada a Objetos (POO): o polimorfismo.
A palavra polimorfismo vem do grego:
- Poli = muitos
- Morfismo = formas
Ou seja, significa “muitas formas”.
Na programação, isso significa que um mesmo objeto pode assumir diferentes comportamentos dependendo da classe que o implementa.
O que é Polimorfismo?
Imagine que você possui vários animais.
Todos eles podem emitir um som.
Entretanto, cada um faz um som diferente.
- Cachorro → Late
- Gato → Mia
- Vaca → Muge
Todos respondem ao mesmo comando:
emitirSom();
Mas cada objeto executa esse método de maneira diferente. Esse é o conceito de polimorfismo.
Utilizando Polimorfismo
Primeiro criamos uma classe base.
public class Animal {
public void emitirSom() {
System.out.println("Animal fazendo som...");
}
}
Agora criamos as subclasses.
Cachorro
public class Cachorro extends Animal {
@Override
public void emitirSom() {
System.out.println("Au Au!");
}
}
Gato
public class Gato extends Animal {
@Override
public void emitirSom() {
System.out.println("Miau!");
}
}
Vaca
public class Vaca extends Animal {
@Override
public void emitirSom() {
System.out.println("Muuuu!");
}
}
Observe que todas possuem o método emitirSom(), mas cada uma possui sua própria implementação.
Criando objetos
Animal a1 = new Cachorro();
Animal a2 = new Gato();
Animal a3 = new Vaca();
Repare em algo interessante.
O tipo da variável é sempre:
Animal
Mas o objeto criado pode ser qualquer subclasse.
Chamando o método
a1.emitirSom();
a2.emitirSom();
a3.emitirSom();
Saída:
Au Au!
Miau!
Muuuu!
Mesmo utilizando uma variável do tipo Animal, o Java identifica automaticamente qual método deve ser executado.
Esse comportamento é chamado de Despacho Dinâmico (Dynamic Dispatch).
O papel do @Override
Sempre que sobrescrevemos um método da superclasse utilizamos a anotação:
@Override
Ela informa ao compilador que aquele método já existe na classe pai.
Caso o nome esteja errado, o Java gera erro de compilação.
Exemplo correto:
@Override
public void emitirSom() {
}
Exemplo incorreto:
@Override
public void emitirSoom() {
}
O compilador detectará que não existe esse método na classe pai.
Vantagens do Polimorfismo
O uso do polimorfismo traz diversos benefícios.
- Código mais limpo
- Menos estruturas
ifeswitch - Fácil manutenção
- Maior reutilização de código
- Facilidade para adicionar novas funcionalidades
- Melhor organização do sistema
- Menor acoplamento entre as classes
Polimorfismo na vida real
Imagine um controle remoto.
Ele possui um botão chamado:
Ligar
Dependendo do aparelho conectado, o comportamento muda.
- TV → Liga a televisão.
- Ar-condicionado → Liga o ar.
- Projetor → Liga o projetor.
O botão é sempre o mesmo.
Quem muda é o objeto que recebe a ação.
Isso é exatamente o que acontece com o polimorfismo.
O polimorfismo permite que objetos diferentes respondam ao mesmo método de maneiras diferentes.
Em Java, ele é obtido principalmente por meio da herança, da sobrescrita de métodos (@Override) e também através de interfaces.
Esse conceito torna os sistemas mais organizados, flexíveis e preparados para crescer sem exigir alterações constantes no código existente.
Quando utilizado em conjunto com encapsulamento, herança, agregação e composição, o polimorfismo forma um dos pilares fundamentais da Programação Orientada a Objetos.
