POO
Desvendando a Orientação a Objetos em Java: Guia Prático com Exemplos
Vamos desmistificar os quatro pilares da POO em Java com exemplos práticos e diretos ao ponto. Vamos lá?
O que é Programação Orientada a Objetos?
Em poucas palavras, a POO é um modelo de programação que utiliza "objetos" para representar coisas e conceitos. Pense em um carro: ele tem características (cor, marca, ano) e comportamentos (acelerar, frear, buzinar). Na POO, as características são os atributos e os comportamentos são os métodos. Tudo isso é agrupado em uma "planta" chamada classe.
🔐 Encapsulamento: Protegendo Seus Dados
O encapsulamento é o princípio de esconder os detalhes internos de um objeto e expor apenas o necessário. Isso protege os dados de modificações acidentais e mantém o código organizado. Em Java, usamos modificadores de acesso como private
para os atributos e métodos públicos (public
), conhecidos como getters e setters, para interagir com eles.
Exemplo Prático:
Vamos criar uma classe ContaBancaria
. O saldo (saldo
) deve ser privado para que ninguém possa alterá-lo diretamente sem passar por uma verificação.
Java
public class ContaBancaria {
private double saldo;
public ContaBancaria(double saldoInicial) {
this.saldo = saldoInicial;
}
// Getter para obter o saldo
public double getSaldo() {
return saldo;
}
// Método público para depositar de forma segura
public void depositar(double valor) {
if (valor > 0) {
this.saldo += valor;
System.out.println("Depósito de R$" + valor + " realizado com sucesso.");
} else {
System.out.println("Valor de depósito inválido.");
}
}
// Método público para sacar
public void sacar(double valor) {
if (valor > 0 && valor <= this.saldo) {
this.saldo -= valor;
System.out.println("Saque de R$" + valor + " realizado com sucesso.");
} else {
System.out.println("Saldo insuficiente ou valor inválido.");
}
}
}
Como usar:
Java
ContaBancaria minhaConta = new ContaBancaria(1000.0);
// System.out.println(minhaConta.saldo); // Erro! O atributo é privado.
System.out.println("Saldo atual: R$" + minhaConta.getSaldo()); // Jeito certo
minhaConta.depositar(500.0);
minhaConta.sacar(200.0);
System.out.println("Saldo final: R$" + minhaConta.getSaldo());
🎭 Polimorfismo: Muitas Formas, Uma Ação
Polimorfismo (do grego, "muitas formas") é a capacidade de um objeto ser referenciado de múltiplas maneiras. Em Java, isso geralmente acontece com a sobreposição de métodos (overriding). Uma classe filha pode ter uma implementação específica para um método que já existe em sua classe mãe.
Exemplo Prático:
Imagine que temos uma classe Animal
com um método fazerSom()
. Cães e gatos fazem sons, mas de maneiras diferentes.
Java
// Classe mãe
class Animal {
public void fazerSom() {
System.out.println("O animal faz um som");
}
}
// Classes filhas
class Cachorro extends Animal {
@Override // Sobrescrevendo o método
public void fazerSom() {
System.out.println("O cachorro late: Au au!");
}
}
class Gato extends Animal {
@Override // Sobrescrevendo o método
public void fazerSom() {
System.out.println("O gato mia: Miau!");
}
}
Como usar:
O poder do polimorfismo brilha aqui. Podemos tratar tanto Cachorro
quanto Gato
como se fossem simplesmente Animal
.
Java
Animal meuCachorro = new Cachorro();
Animal meuGato = new Gato();
meuCachorro.fazerSom(); // Saída: O cachorro late: Au au!
meuGato.fazerSom(); // Saída: O gato mia: Miau!
blueprint Classe Abstrata: O Esqueleto do Negócio
Uma classe abstrata é como um modelo semi-pronto. Ela pode ter tanto métodos concretos (com implementação) quanto métodos abstratos (sem implementação). Classes que herdam de uma classe abstrata são obrigadas a implementar os métodos abstratos.
Quando usar? Use uma classe abstrata quando você tem um conjunto de classes que compartilham uma estrutura e comportamento comuns, mas alguns detalhes de implementação são específicos para cada uma.
Exemplo Prático:
Pense em um Veiculo
. Todo veículo tem um motor que pode ser ligado (comportamento comum), mas a forma como ele se move pode variar (carro acelera, barco navega).
Java
// Classe abstrata
abstract class Veiculo {
private String marca;
// Construtor
public Veiculo(String marca) {
this.marca = marca;
}
// Método concreto (compartilhado por todos os filhos)
public void ligar() {
System.out.println("O veículo " + marca + " ligou o motor.");
}
// Método abstrato (deve ser implementado pelos filhos)
public abstract void mover();
public String getMarca() {
return marca;
}
}
class Carro extends Veiculo {
public Carro(String marca) {
super(marca);
}
@Override
public void mover() {
System.out.println("O carro " + getMarca() + " está acelerando na estrada.");
}
}
Como usar:
Java
// Veiculo meuVeiculo = new Veiculo("Genérico"); // Erro! Não se pode instanciar classe abstrata.
Carro meuCarro = new Carro("Fiat");
meuCarro.ligar();
meuCarro.mover();
📜 Interface: O Contrato de Funcionalidades
Uma interface é um "contrato" que define um conjunto de métodos que uma classe deve implementar. Ela não contém nenhuma implementação, apenas as assinaturas dos métodos. Uma classe pode implementar múltiplas interfaces, o que resolve a limitação do Java de só poder herdar de uma única classe.
Quando usar? Use uma interface quando quiser definir um "papel" ou uma "capacidade" que diferentes classes podem ter, mesmo que não tenham uma relação de herança direta. Ex: "ser serializável", "ser clicável", "ser voável".
Exemplo Prático:
Vamos definir a capacidade de Voar
. Tanto um Passaro
quanto um Aviao
podem voar, mas são entidades completamente diferentes.
Java
// A interface define o "o quê", não o "como"
interface Voavel {
void decolar();
void voar();
void aterrissar();
}
class Aviao implements Voavel {
@Override
public void decolar() {
System.out.println("Avião decolando da pista...");
}
@Override
public void voar() {
System.out.println("Avião voando em altitude de cruzeiro.");
}
@Override
public void aterrissar() {
System.out.println("Avião aterrissando na pista.");
}
}
class Passaro implements Voavel {
@Override
public void decolar() {
System.out.println("Pássaro levanta voo do galho.");
}
@Override
public void voar() {
System.out.println("Pássaro batendo asas pelo céu.");
}
@Override
public void aterrissar() {
System.out.println("Pássaro pousa em um fio.");
}
}
Como usar:
Java
Voavel meuAviao = new Aviao();
Voavel meuPassaro = new Passaro();
meuAviao.voar(); // Saída: Avião voando em altitude de cruzeiro.
meuPassaro.voar(); // Saída: Pássaro batendo asas pelo céu.
Conclusão
Dominar a Orientação a Objetos é um passo fundamental para escrever códigos mais limpos, flexíveis e escaláveis em Java.
Encapsulamento protege seus dados.
Polimorfismo permite que seu código seja mais flexível.
Classes Abstratas criam um esqueleto para classes relacionadas.
Interfaces definem contratos ou habilidades que classes não relacionadas podem implementar

Atualizado