Programação Orientada a Objetos e seus Pilares
Tags: software, engineering, development, ruby
Published: 2023-04-01 22:25:03

---
title: Programação Orientada a Objetos e seus Pilares
published: true
description: Programação Orientada a Objetos e seus Pilares
cover_image: https://res.cloudinary.com/practicaldev/image/fetch/s--Xbwv4WJK--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cs3aunpcl2ujm73r08ny.png
tags: 'software, engineering, development, ruby'
series: 'Aprendendo Ruby'
---

A programação orientada a objetos (POO) é um paradigma de programação que se baseia em quatro pilares: Abstração, Encapsulamento, Herança e Polimorfismo. A abstração envolve a identificação das características essenciais de um objeto, o encapsulamento protege o estado interno do objeto, a herança permite a criação de novas classes com base em outras classes já existentes e o polimorfismo permite que objetos de diferentes classes sejam tratados de forma semelhante. Esses pilares são fundamentais para a construção de programas orientados a objetos robustos, flexíveis e de fácil manutenção.

## **Abstração**

É o processo de identificar as características e comportamentos essenciais de um objeto, ignorando os detalhes que não são relevantes para o contexto em que o objeto será utilizado. Isso permite que os programadores possam modelar a realidade de forma mais simplificada e focada nas necessidades do sistema em questão.

- **Exemplo**

Imagine que você está criando um sistema de gerenciamento de biblioteca. Para modelar o objeto `livro`, você pode identificar suas características essenciais, como `título`, `autor`, `ano de publicação`, `número de páginas`, `editora`, etc. e ignorar detalhes que não são relevantes para o sistema, como `cor da capa do livro`.

- **Código**

```ruby
class Livro
  attr_accessor :titulo, :autor, :ano_publicacao, :num_paginas, :editora

  def initialize(titulo, autor, ano_publicacao, num_paginas, editora)
    @titulo = titulo
    @autor = autor
    @ano_publicacao = ano_publicacao
    @num_paginas = num_paginas
    @editora = editora
  end
end
```

- Nesse exemplo, a classe `Livro` possui apenas as características essenciais para o sistema de gerenciamento de biblioteca, como `título`, `autor`, `ano de publicação`, `número de páginas` e `editora`. A cor da capa, por exemplo, não é considerada essencial e não foi incluída na classe. Dessa forma, estamos aplicando o conceito de abstração na modelagem do objeto `Livro`, identificando e separando apenas características essenciais.


## **Encapsulamento**

Principio de ocultar as informações de implementação de um objeto, expondo apenas a interface pública para o usuário. Isso permite que os objetos interajam de forma segura, garantindo que as informações internas não sejam acessadas ou modificadas de forma indevida.

- **Exemplo**

Em um sistema de banco, você pode ter uma classe `Conta Bancária`, que possui informações como número de `conta`, `saldo` e `titular`. Para garantir a segurança dessas informações, você pode encapsular os atributos da classe, definindo-os como privados e criando métodos públicos para acessá-los e modifica-los de forma controlada.

- **Código**

```ruby
class ContaBancaria
  def initialize(numero, saldo, titular)
    @numero = numero
    @saldo = saldo
    @titular = titular
  end

  def saldo
    @saldo
  end

  def depositar(valor)
    @saldo += valor
  end

  def sacar(valor)
    if valor <= @saldo
      @saldo -= valor
    else
      puts "Saldo insuficiente"
    end
  end

  private

  def numero
    @numero
  end

  def titular
    @titular
  end
end
```

- Nesse exemplo, os atributos `numero` e `titular` são definidos como privados através da palavra-chave `private`, o que significa que eles só podem ser acessados dentro da classe. Isso garante que as informações sejam mantidas em segurança e não possam ser modificadas de forma indevida de fora da classe. Os métodos, `saldo` e `depositar` e `sacar` são públicos e permitem que o saldo da conta seja consultado e modificado de forma controlada.

## **Herança**

Processo de criar uma nova classe a partir de uma classe já existente, herdando suas características e comportamentos. Isso permite a reutilização de código, já que as subclasses não precisam implementar todo o código novamente, apenas as partes que precisam ser modificadas ou adicionadas.

- **Exemplo**

Em um jogo, você pode ter classe `Personagem` com atributos e métodos básicos, como `saúde`, `energia`, `ataque` e `movimento`. A partir dessa classe, você pode criar subclasses como `Jogador` e `Inimigo`, herdando os atributos e métodos da classe `Personagem` e adicionando características específicas de cada tipo de personagem.

- **Código**

```ruby
class Personagem
  attr_accessor :saude, :energia, :ataque, :movimento

  def initialize(saude, energia, ataque, movimento)
    @saude = saude
    @energia = energia
    @ataque = ataque
    @movimento = movimento
  end
end

class Jogador < Personagem
  attr_accessor :pontuacao

  def initialize(saude, energia, ataque, movimento, pontuacao)
    super(saude, energia, ataque, movimento)
    @pontuacao = pontuacao
  end

  def aumentar_pontuacao(valor)
    @pontuacao += valor
  end
end

class Inimigo < Personagem
  attr_accessor :recompensa

  def initialize(saude, energia, ataque, movimento, recompensa)
    super(saude, energia, ataque, movimento)
    @recompensa = recompensa
  end

  def aumentar_recompensa(valor)
    @recompensa += valor
  end
end
```

- Nesse exemplo, a classe `Personagem` é a classe base ou classe pai, que define os atributos é métodos básicos de um personagem. As classes `Jogador` e `Inimigo` são subclasses ou classes filhas que herdam esses atributos e métodos da classe `Personagem`, mas adicionam características específicas, como a `pontuação` e a recompensa, respectivamente. O método `super` é usado nas subclasses para chamar o construtor de classe pai e inicializar seus atributos.

## **Polimorfismo**

Capacidade de objetos de uma mesma classe ou de classes diferentes responderem a uma mesma mensagem de maneiras diferentes. Isso permite a criação de código mais flexível e genérico, que pode ser aplicado a diferentes contextos e situações.

- **Exemplo**

Em um sistema de formas geométricas, você pode ter uma classe  `Forma` com um método `CalcularÁrea`. A partir dessa classe, você pode criar subclasses como `Retângulo` e `Círculo`, que implementam o método `CalcularÁrea` de formas diferentes, dependendo de suas características específicas. Quando você chama o método `CalcularÁrea` em um objeto de uma dessas subclasses, ele responderá de forma diferente, mesmo que a chamada seja feita a partir da classe `Forma`.

- **Código**

```ruby
class Animal
  def falar
    puts "Este animal não sabe falar!"
  end
end

class Cachorro < Animal
  def falar
    puts "Au Au!"
  end
end

class Gato < Animal
  def falar
    puts "Miau!"
  end
end

# Criando objetos de diferentes classes
animal = Animal.new
cachorro = Cachorro.new
gato = Gato.new

# Chamando o método "falar" em cada objeto
animal.falar # "Este animal não sabe falar!"
cachorro.falar # "Au Au!"
gato.falar # "Miau!"
```

- Nesse exemplo, as classes `Cachorro` e `Gato` herdam a classe `Animal` e implementam o método `falar` de forma diferente, para produzir o som característico de cada animal. Quando chamamos o método `falar` em cada objeto, é identificado a classe de cada objeto e chama o método correspondente a essa classe, permitindo que os objetos de diferentes classes sejam tratados de forma semelhante. Isso é um exemplo de polimorfismo.