Abstração
A abstração consiste em isolar as características essenciais de um objeto, focando no que ele faz em vez de como ele faz. Em Java, isso é implementado através de classes e métodos abstratos.
Classes Abstratas: São classes que não podem ser instanciadas diretamente. Elas servem como modelos para outras classes. Se uma classe possui ao menos um método abstrato, ela obrigatoriamente deve ser declarada como abstrata utilizando a palavra-chave abstract.
public abstract class Veiculo {
private String marca;
// Construtor para ser usado pelas subclasses
public Veiculo(String marca) {
this.marca = marca;
}
// Método abstrato: define o contrato sem implementação
public abstract void emitirSom();
}
Métodos Abstratos: São declarações de métodos sem corpo (sem chaves), finalizados com ponto e vírgula. As subclasses não abstratas que herdam de uma classe abstrrata são obrigadas a implementar todos os seus métodos abstratos.
Encapsulamento
O encapsulamento visa proteger os dados internos de uma classe, controlando o acesso a eles através de modificadores de visibilidade. Isso reduz o acoplamento e facilita a manutenção do código.
Para implementar o encapsulamento, seguimos dois passos fundamentais:
- Privatização de Atributos: Define-se os campos da classe como
privatepara impedir o acesso externo direto. - Métodos de Acesso (Getters e Setters): Disponibiliza-se métodos públicos para leitura e modificação controlada dos dados.
public class ContaBancaria {
private double saldo;
public double getSaldo() {
return this.saldo;
}
public void depositar(double valor) {
if (valor > 0) {
this.saldo += valor;
}
}
}
Herança
A herança permite que uma classe (subclasse) herde atributos e comportamentos de outra classe (superclasse), promovendo o reuso de código. Em Java, utiliza-se a palavra-chave extends.
- Herança Única: Uma classe pode estender apenas uma única superclasse.
- Palavra-chave super: Utilizada para acessar membros ou construtores da classe pai.
- Palavra-chave final: Quando aplicada a uma classe, impede que ela seja herdada. Se aplicada a um método, impede que ele seja sobrescrito.
public class Carro extends Veiculo {
private int portas;
public Carro(String marca, int portas) {
super(marca); // Chama o construtor da superclasse
this.portas = portas;
}
@Override
public void emitirSom() {
System.out.println("O carro está buzinando.");
}
}
Além do extends, existe a palavra-chave implements, que permite que uma classe adote o comportamento definido em uma ou mais interfaces, simulando uma forma de herança múltipla de tipos.
Polimorfismo
O polimorfismo permite que um objeto seja tratado de diversas formas. Na prática, uma referência de uma superclasse pode apontar para um objeto de qualquer uma de suas subclasses.
Os requisitos básicos para o polimorfismo são:
- Relação de Herança ou implementação de Interface.
- Sobrescrita de métodos (Override).
- A referência do tipo genérico (pai) apontando para uma instância específica (filho).
public class TestePolimorfismo {
public static void main(String[] args) {
// Referência do tipo Veiculo, objeto do tipo Carro
Veiculo meuMeioTransporte = new Carro("Toyota", 4);
// Chamada polimórfica: o método executado é o da classe Carro
meuMeioTransporte.emitirSom();
}
}
Em Java, o polimorfismo é sustentado pelo mecanismo de vinculação dinâmica (dynamic binding), onde a implementação exata a ser executada é decidida em tempo de execução com base no objeto real, e não no tipo da variável de referência.