---
# System prepended metadata

title: Conceitos de Programação Orientada a Objetos (POO)

---

# Conceitos de Programação Orientada a Objetos (POO)

## Pilares da programação orientada a objetos

### 1) Abstração
![](https://i.imgur.com/b38g1xp.png)

* Conceito relacionado à capacidade de obter apenas características relevantes de um contexto (uma conta de banco, um produto, uma pessoa etc.) para possibilitar a criação de uma Classe.
* Na imagem acima, temos alguns casos de abstração, de modo que foram selecionados apenas aspectos importantes, naquele contexto, para compor determinada entidade.

### 2) Encapsulamento
![](https://i.imgur.com/wNGVyOX.png)

* O encapsulamento é uma maneira de proteger o código, de modo que o acesso direto aos atributos de uma classe fica restringido. Também é possível criar restrições a determinados métodos.
* É possível ter acesso aos atributos de uma classe encapsulada por meio dos métodos ***getters*** e ***setters***.
* Não importa a forma utilizada para realizar um determinado procedimento, e sim se o resultado esperado de uma funcionalidade será entregue.
* Torna um software mais flexível, pois facilita a manutenção e a criação de novas utilidades.



---

###  3) Herança
![](https://i.imgur.com/4l5U6Og.png)

* A classe que está sendo gerada (**subclasse**) herda todos os atributos e métodos da classe geradora (**superclasse**).
* Na imagem acima, quanto mais longe da classe Animal mais **especializada** é a classe e quanto mais próximo mais **genérica** é a classe.
* Nesse pilar da POO é importante saber as palavras-chave ***abstract*** e ***final***. Esses conceitos podem ser aplicados para classes e métodos e ganharão os seguintes comportamentos:
    - **Classe abstrata**: não pode ser instanciada. Serve de "molde" para as subclasses.
    - **Método abstrato**: declarado, mas não implementado. Basta uma classe ter um método abstrato para ela também ser abstrata. Além disso, caso uma subclasse herde um método abstrato, é obrigatório sobrescrever (conceito muito utilizado em Polimorfismo, outro pilar da POO) esse método com uma implementação.
    - **Classe final**: não pode ser herdada.
    - **Método final**: não pode ser sobrescrito por uma subclasse.
* Aqui também entra o termo ***protected***, um modificador de acesso que possibilita que apenas subclasses tenham acesso aos atributos de suas superclasses. Caso os atributos da superclasse fossem ***private***, nem as subclasses teriam acesso, sendo necessários os métodos *getters* e *setters*.
* Por fim, não é possível que uma subclasse *extends* duas superclasses, ou seja, não é permitido a herança múltipla na implementação clássica do Java. No entanto, é possível que uma classe esteja vinculada a mais de uma interface.


---
###  4) Polimorfismo
![](https://i.imgur.com/DHzXkUR.png)

* **Polimorfismo de sobreposição (*Override*)**: 
    - Como citado no tópico método abstrato, caso uma subclasse estenda uma classe abstrata que possua métodos abstratos, é obrigatório que esses métodos abstratos sejam sobrescritos e implementados nessa subclasse.
    - No caso da imagem acima, a classe abstrata *Funcionário* possui um método abstrato *calculoSalario()* e as especializações PessoaFisica e PessoaJuridica possuem seus próprios métodos de *calculoSalario()* (métodos com a mesma assinatura, mas com comportamentos distintos), ou seja, o método abstrato da superclasse é sobrescrito e implementado de diferentes formas nas subclasses.
    - A associação (*upcasting*) do tipo específico (subclasse) com o tipo genérico (superclasse), por exemplo "Funcionario funcionario = *new* PessoaFisica("João", 35)", é feita em tempo de execução.



---

## Outros tópicos

### - Interface

* Interface é um tipo que define um conjunto de operações que uma determinada classe deve implementar.
* Na definição das interfaces há apenas a assinatura dos métodos, cabendo à classe que implementar essa interface definir o que for necessário.
![](https://i.imgur.com/AyRPiXh.png)

### - Inversão de controle / injeção de dependência

* Inversão de controle: padrão de desenvolvimento que consiste em retirar da classe a responsabilidade de instanciar suas dependências.
* Injeção de dependência: maneira de realizar a inversão de controle. Um componente externo faz a instância da dependência (interface) e, após isso, é injetada no objeto "pai". Pode ser implementada por meio de um construtor (implementação da interface/dependência entra como argumento do construtor), por exemplo.
![](https://i.imgur.com/8D9a9By.png)
![](https://i.imgur.com/x96uXKI.png)
![](https://i.imgur.com/YUrhcGF.png)
* No caso acima, a classe *BrazilTaxService* implementa a interface *TaxService* e a instanciação dessa dependência é realizada fora da classe *RentalService*. Além disso, a injeção de dependência ocorre por meio do construtor da classe *RentalService*.
* Dessa maneira, o código fica mais flexível, tendo em vista que a classe *RentalService* pode receber qualquer implementação da interface *TaxService*, como *GermanyTaxService*, *PortugalTaxService* etc.