POO | Programação Orientada a Objetos

🎯 Programação Orientada a Objetos

Paradigma essencial para construir sistemas escaláveis, reutilizáveis e de fácil manutenção

⚡ Pilares: Abstração • Encapsulamento • Herança • Polimorfismo

📦 1. Abstração

Modelar entidades do mundo real em classes, focando apenas nas características e comportamentos essenciais.

// Classe que abstrai um Carro class Carro { constructor(marca, modelo) { this.marca = marca; this.modelo = modelo; this.velocidade = 0; } acelerar() { this.velocidade += 10; console.log(`${this.marca} acelerou para ${this.velocidade}km/h`); } frear() { this.velocidade -= 5; console.log(`${this.marca} reduziu para ${this.velocidade}km/h`); } }
💡 Abstração esconde complexidade e expõe apenas o necessário para interação.

🔒 2. Encapsulamento

Proteger dados internos, expondo apenas métodos controlados de acesso (getters/setters).

class ContaBancaria { #saldo = 0; // atributo privado (JavaScript) depositar(valor) { if (valor > 0) this.#saldo += valor; } getSaldo() { return this.#saldo; } } const conta = new ContaBancaria(); conta.depositar(100); console.log(conta.getSaldo()); // 100 // conta.#saldo → erro! privado
💡 Encapsulamento previne estados inconsistentes e facilita manutenção.

🧬 3. Herança

Reutilizar código: classes filhas herdam atributos e métodos da classe pai.

class Animal { constructor(nome) { this.nome = nome; } emitirSom() { console.log("Som genérico"); } } class Cachorro extends Animal { emitirSom() { console.log("Au au!"); } latir() { console.log("Woof!"); } } const rex = new Cachorro("Rex"); rex.emitirSom(); // Au au!
💡 Evite herança profunda (max 3 níveis). Prefira composição quando possível.

🔄 4. Polimorfismo

Um mesmo método pode ter comportamentos diferentes em classes distintas.

class Forma { area() { return 0; } } class Circulo extends Forma { constructor(raio) { super(); this.raio = raio; } area() { return Math.PI * this.raio ** 2; } } class Retangulo extends Forma { constructor(base, altura) { super(); this.base = base; this.altura = altura; } area() { return this.base * this.altura; } } const formas = [new Circulo(5), new Retangulo(4, 6)]; formas.forEach(f => console.log(f.area())); // 78.54 e 24
💡 Polimorfismo permite código mais flexível e extensível.

🏗️ Classes e Objetos

Classe: molde/blueprint. Objeto: instância concreta.

// Definição da classe class Pessoa { constructor(nome, idade) { this.nome = nome; this.idade = idade; } apresentar() { return `Olá, sou ${this.nome} e tenho ${this.idade} anos.`; } } // Criando objetos const pessoa1 = new Pessoa("Ana", 28); const pessoa2 = new Pessoa("Carlos", 35); console.log(pessoa1.apresentar()); console.log(pessoa2.apresentar());

🔧 Métodos Especiais

  • Construtor: inicializa o objeto
  • Getters/Setters: controlam acesso a atributos
  • Métodos estáticos: pertencem à classe, não à instância
class Utilitarios { static somar(a, b) { return a + b; } } console.log(Utilitarios.somar(5, 3)); // 8 // não precisa instanciar

📐 Princípios SOLID

  • S - Single Responsibility
  • O - Open/Closed
  • L - Liskov Substitution
  • I - Interface Segregation
  • D - Dependency Inversion
🎯 SOLID é a base para código limpo e sustentável em POO.

⚖️ POO vs Outros Paradigmas

ParadigmaCaracterísticasQuando usar
🟢 Orientado a ObjetosEstado + comportamento, encapsulamentoSistemas complexos, UI, jogos, negócios
🔵 FuncionalImutabilidade, funções purasProcessamento de dados, concorrência
🟠 ProceduralSequência de instruçõesScripts simples, algoritmos
🟣 DeclarativoO que fazer, não comoSQL, HTML, CSS

📝 Exercícios de Fixação

1. Criar classe ContaBancaria

Crie uma classe ContaBancaria com atributos privados (saldo, titular). Implemente métodos depositar(), sacar() e getSaldo().

2. Herança: Funcionário

Crie uma classe Funcionario com atributos nome e salario. Depois crie Gerente que herda e adiciona bonus.

3. Polimorfismo com Formas

Implemente uma hierarquia de formas (Forma, Circulo, Quadrado) com método calcularArea().

4. Encapsulamento com Getters/Setters

Crie uma classe Produto com atributo privado preco, e valide que o preço nunca seja negativo.

5. Composição vs Herança

Crie um exemplo de composição onde um Carro possui um Motor (em vez de herdar de Veiculo).

✅ Boas Práticas em POO

  • ✔️ Uma classe, uma responsabilidade (SRP)
  • ✔️ Prefira composição sobre herança
  • ✔️ Use nomes significativos para classes e métodos
  • ✔️ Mantenha encapsulamento forte
  • ✔️ Programe para interfaces, não para implementações
  • ✔️ Evite herança profunda (max 3 níveis)

🚀 Padrões de Projeto Essenciais

  • Singleton: única instância global
  • Factory: criação de objetos centralizada
  • Observer: eventos e notificações
  • Strategy: algoritmos intercambiáveis
  • Dependency Injection: reduz acoplamento
💡 Design Patterns são soluções consagradas para problemas recorrentes.

📚 Referências

  • "Design Patterns" – GoF (Erich Gamma et al.)
  • "Clean Code" – Robert C. Martin
  • "Head First Design Patterns"
  • Documentação oficial das linguagens: Java, C#, Python, JavaScript/TypeScript

Nenhum comentário

Tecnologia do Blogger.