Introdução à Programação Orientada a Objetos
Published: 2021-04-27 15:59:27

E aí, galerinha! 

Já ouviu falar em POO? É uma sigla, em português, que significa Programação Orientada a Objetos; em inglês, OOP (Object-Oriented Programming). Este artigo é uma síntese de conceitos importantes para utilizar quando implementado esse paradigma de programação tão amplamente utilizado. Utilizarei como base POO Java, alguns aspectos podem mudar de acordo com a linguagem utilizada. Procure ler documentação disponível na web.
Pegue um café, e vamos nessa!
![Alt text of image](https://media.giphy.com/media/l2SpXensc5RhNzfK8/giphy.gif)


O que é um objeto?
Um objeto, não necessariamente precisa ser algo **concreto**, pode ser abstrato, percebido pelos sentidos e que possua **comportamentos, estado atual e características**. Por exemplo, um celular possui:
- Características: cor, tamanho, marca, memória; 
- Estado: ligado, desligado, reiniciando; 
- Comportamentos (o que é possível ser feito?): fazer gravações, fotos, vídeos. 
O objeto ‘celular’, pode ser representado por uma classe. 
Representar significa listar os comportamentos, estado atual e características sem atribuição de valor. Então, estamos dizendo que o celular possui uma cor, mas não sabemos ainda qual, essa atribuição acontece em outra classe.  

**Classe** 
É um tipo estruturado que pode conter membros:
 • Atributos (dados / campos)
 • Métodos (funções / operações)

Vamos criar a classe ‘Celular’. Inicialmente, pelos atributos desta classe (ou seja, suas características).

Classe Celular 
cor:              Caractere
tamanho:     Real
marca:         Caractere
carga:          Inteiro
ligado :        Lógico

Metodo ligar()
ligado = verdadeiro
FimMetodo

Metodo digitar()
	se (ligado = falso) entao
	Escreva(“Erro”)
	senao
	Escreva(“Digitando”)

FimClasse

<imgcelular1> 

Com a classe ‘Celular’ feita, nós podemos **criar um objeto** na classe principal. Esse processo é chamado de instanciamento.
Para que o instanciamento aconteça, é preciso inserir informações nos atributos e métodos. Sendo assim, a classe é o molde do objeto celular, a representação. Então, qual seria o objeto em si?
**Instanciar**
celular1 = new Celular()




![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s0kr8rv671r1rka1rt6c.JPG)

Nós utilizamos o modificador de acesso “private”, então o sistema não permite a alteração direta no atributo em outras classes, por motivos de segurança - irei abordar esse assunto mais para frente.

**Boas práticas**
	Classes geralmente são escritas com inicial maiúscula; atributos e métodos em letra minúscula e os métodos possuem parênteses, bem como seu tipo de **retorno**. 
	exemplo de método: 
	public String abrir()

public -> visibilidade
String -> tipo retorno
abrir() -> nome do método

**Pacotes e Imports**
Com o intuito de manter organizado e de fácil manutenção, o projeto pensado é dividido em classes dentro de pacotes. Veja esse exemplo:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gmn8ehaqy4zfjnopgytv.JPG)

Um projeto possui vários pacotes e classes, para que uma classe acesse a outra é utilizado a palavra-chave _import_ seguida do pacote em que ela está e seu nome, por exemplo 'import entities.Celular' é um import realizado na classe Main.java (utilizada como classe principal).  

**Visibilidade do Objeto**
	Para melhor proteção de informações do sistema, é possível determinar os **modificadores de acesso**. A prática mais comum é a proteção de seus atributos com o modificador de acesso _private_. Entende-se que as classes são responsáveis pelos seus atributos, muitas vezes não é interessante que outras classes saibam da existência de certos atributos. A seguir, os tipos de modificadores e quais classes podem acessá-los.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d1b3l8mx8ciu656gq4ue.JPG)

**Construtores**
O nome é intuitivo, ele serve para construir o objeto.
Cria-se na classe ‘Celular’, e utiliza-se no momento da criação do objeto, na nossa classe ‘Main’, através do operador new. 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3fa2jd5actlqwc5nqn69.JPG)

A classe Main.java importou a classe Celular.java e instanciou o objeto celular1.

package application;

**import entities.Celular;**

public class Main {

	public static void main(String[] args) {
		
		Celular celular1 = new Celular();
		
	}

}

Uma observação importante, os construtores são os últimos a serem lidos pelo Java Virtual Machine, independente da sua posição no código.

**Encapsulamento: métodos getters e setters**
Como manter os atributos protegidos através do “private” e também acessá-los na classe Main.java? Essa possibilidade é presente por meio dos métodos get/set. O get retorna o atributo, enquanto o set o modifica. Cabe também a observação de que alguns atributos não poderão ter o método ‘set’, para que não seja alterado em hipótese alguma.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kq7fkzq7z6jmy020g3f8.JPG)

A palavra ‘this’ presente nos métodos indica o atributo local. Essa cor recebe um novo valor que será definido quando o set for solicitado:
ESSA.cor RECEBE cor

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u7ealmcywcadl5vl0uph.JPG)
Agora, o objeto celular1 possui valor no atributo cor graças ao nosso incrível encapsulamento setCor. 


**Herança**
Uma situação comum é a ocorrência de classes com alguns atributos iguais. Vamos deixar o projeto do celular de lado e criar um novo, por exemplo, classe Vendedor. java e Cliente.java podem conter os seguintes atributos em comum: cpf, endereco, nome, telefone, email. Então, com o intuito de evitar a repetição e aprimorar o código, utiliza-se a Herança. Herdar significa ter uma classe de origem chamada de ‘classe mãe’ e os seus herdeiros que são filhos recebendo as características da mãe. Outra nomenclatura comum é ‘superclasse’ Pessoa.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fidhlniarj10xsxu8df6.JPG)

Esse tipo de estrutura facilita muito na adição de futuras informações, por exemplo, caso pretenda inserir o atributo “numeroRG”, só seria necessário a atribuição na classe Pessoa.java, ao invés de adicionar em cada uma das classes Cliente.java e Vendedor.java.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mhb0u0lqnljfwlgwezxe.JPG)

Classe Pessoa.java criada. Para que as outras duas classes possam herdar os atributos e métodos basta adicionar a palavra EXTENDS e o nome da classe:
public class Cliente extends Pessoa
public class Vendedor extends Pessoa

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ir8szxw4x52w1v198xiu.JPG)


Depois disso, podemos instanciar um objeto na classe Main.java. Observe que ao digitar cliente.get há sugestões de escrita incluindo os métodos getters do tipo Pessoa, a superclasse.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5lznrmvsb19xrdj1d71r.JPG)

Também é possível instanciar o objeto com a superclasse como tipo, mas isso faz com que somente exista os atributos e métodos da classe Pessoa.java


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sema5rgoxdkl1iqon7xe.JPG)


**Polimorfismo**

A palavra já diz muito, “poli”: muitos; “morfo”: formas; polimorfismo, muitas formas. 
Como visto anteriormente, a classe filha herda atributos e métodos de sua classe pai, entretanto pode haver a necessidade de mudança em algum aspecto do método herdado, então utiliza-se o polimorfismo para alterá-lo somente na classe filha. A palavra @Override é muito utilizada para sobrescrever os métodos nas classes filhas.
Então, criei um método chamado obterEndereco() na classe mãe Pessoa.java, sobrescrevi o mesmo método nas classes filhas, porém com mudanças particulares.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hsweevlnib3jxw9dq9xk.JPG)

Em seguida, atribui o valor do endereço de cada um dos objetos instanciados, por meio do ‘set’ (Encapsulamento). Por fim, ao chamar o método obterEndereco() para cada um dos objetos instanciados, é respeitado as particularidades das classes.
Veja na parte inferior da imagem o que é impresso no console.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qai4ip5mrs6kc3nenp37.JPG)

Legal, né? 
Lembre-se que isso foi uma forma mais direta de explicar, sem muitos rodeios e detalhes em cada assunto.

Recomendo fortemente que acesse as referências para maior profundidade no assunto de POO, bem como outras explicações.

Referências
https://www.caelum.com.br/apostila-java-orientacao-objetos
https://www.devmedia.com.br/os-4-pilares-da-programacao-orientada-a-objetos/9264