Entendendo Programação Orientada a Objetos, de vez, com Harry Potter.
Tags: poo, programming, python, oop
Published: 2022-09-13 03:41:09

> "Castigo do monstro, sim ele voltou aquele que é o mais temido de todas as edições…" - Ivy, bbb 20

Vem ai a **Programação Orientada a Objetos** e se você como eu, fez parte de uma maioria que não entendeu direito na faculdade, eu to aqui para te ajudar a entender, sim, pedi ajuda ao Dumbledore.

![dumbledore](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jmbz72j2jlh2rqufcb8v.jpeg)

Oi **pessoALL**, agora sim, tudo bem com vocês? Atualmente, sou professora no **[Luiza<Code>](https://conteudo.carreiras.magazineluiza.com.br/luiza-code-5-edicao-inscricao)**, que é programa de formação em tecnologia, exclusivo para mulheres, criado pelo **Magalu**. Estamos na 5° edição e novamente fui/sou a responsável pelo módulo de POO.
No decorrer do curso recebi alguns feedbacks interessantes e inspiradores:

![feedback carmen](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x92lp6yrfr4adn8clkmp.jpeg)

![feedback lilian](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j80gxi3w5xrr236uavsv.png)

Fiquei imensamente feliz por ter conseguido deixar claro o módulo para elas, assim como pela criatividade e todo o empenho que elas tiveram do início ao fim.
Vendo que foi bastante positivo, resolvi transformar um pouco do que foi ensinado em um artigo, e ao longo dele vou explicar para vocês a parte teórica de POO e a parte prática, com **python**, vamos aprender como poderíamos/podemos aplicar na vida real.
Antes de tudo, programação orientada a objetos é um **[paradigma de programação](https://en.wikipedia.org/wiki/Programming_paradigm)** que tenta **emular problemas do mundo real**, usando o conceito **abstrato** de objetos, como uma estrutura de dados que pode ser alterada e referenciada.

**Dito de outra forma…**

Programação orientada a objetos é uma **abordagem para modelar coisas concretas do mundo real**, como carros, bem como relações entre coisas, como empresas e funcionários, alunos e professores e assim por diante. POO modela entidades do mundo real como objetos de software que possuem alguns dados associados a eles e podem executar determinadas funções.
E quais as vantagens? Bom, vamos entender em uma analogia simples:
João, Maria e Alice vão a uma pizzaria, porém, cada um deles tem um sabor preferido de pizza.
João gosta de pizza de mussarela, Maria gosta de pizza de calabresa e Alice de palmito. Todas as pizzas tem a mesma base e molho, o que muda é a cobertura.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g97c51prrhwxtdltt5z9.png)
Se o pizzaiolo optar por economia de tempo, ele vai triplicar a massa e o molho em uma só receita, finalizar mudando apenas a cobertura, caso contrário, ele terá que construir 3 massas, 3 molhos e assim por diante.

Em POO, a facilidade de pegar as partes em comum e modularizar nos trás algumas vantagens, como **redução de custos**,**economia em tempo e esforço**, **facilidade de alteração/manutenção do código**, etc.

**E o que são objetos?**

Os objetos são as **base do POO **e pode ser **qualquer coisa que represente coisas da vida real**, é **uma entidade que encapsula dados e comportamentos**, onde comportamento é o conjunto de funções (métodos) que operam nesses dados.

![calculadora](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2alouid5lt5jcivz43np.png)

Observe a calculadora, podemos notar que os atributos são sempre adjetivos, enquanto os comportamentos (métodos) são sempre os verbos

**E classes?**

Uma classe é uma **coleção de objetos com características semelhantes**.

![classe](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2jewe2jckfrdy795n2ua.png)

São usadas para criar estruturas de dados definidas pelo usuário. As classes definem funções, que identificam os comportamentos e ações que um objeto criado a partir da classe pode realizar com seus dados.

Uma classe é um modelo de como algo deve ser definido. Na verdade, ele não contém nenhum dado. Já a instância, que é um objeto que é construído a partir de uma classe, irá conter os valores reais.

### Os principais pilares de POO
O paradigma de POO é um campo vasto e aplicado em diferentes linguagens de programação, dito isso, temos a necessidade de entender o que o abrange: seus quatro principais pilares.

![pilares poo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ds527sf6c04ltgfzzg0w.png)

### Aprendendo com Harry Potter
No decorrer, vamos aprender a teoria por trás de cada pilar e a prática associando ao universo do bruxinho mais famoso da atualidade.

#### Herança

Podemos definir, como o processo onde uma classe adquire as propriedades e comportamento de outra.

É muito útil para classes que repetem basicamente as mesmas coisas, quando isso acontece, é interessante criar uma classe base e para cada classe que tiver comportamentos e propriedades semelhantes, eu faço uma extensão da classe principal.

Observe a imagem abaixo, a classe base é a mãe e a subclasse é a filha, pode acontecer também de uma classe estender/herdar duas classes, chamamos de: classe múltipla.


![heranca](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m16covouejxw1gh4xn70.png)

Lembra quando eu falei que POO emula problemas do mundo real? Claramente quando Dumbledore fala para Harry que ele se parece com o pai e tem os olhos da mãe, vemos um exemplo claro de herança.

No exemplo do código abaixo, foi feito uma herança de bruxos. A partir da classe base _Witch_ podemos criar bruxos herdando comportamentos e atributos, além dos seus próprios, caso tenham.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cneopwysxve2z4mtr7rv.png)

{% embed https://gist.github.com/thaisribeiro/25636f78eb8bdd2af657d9506a04431e %}

#### Abstração
A abstração é um processo de ocultar os detalhes de implementação do usuário, apenas a funcionalidade será fornecida.

Dito de outra forma, o usuário tem acesso apenas a informação sobre o que o objeto faz ao invés de como ele faz.
Um exemplo clássico de abstração é o caixa eletrônico, quando vamos sacar dinheiro, sabemos como sacar, não necessariamente precisamos entender o que o caixa faz.

Uma abstração pode ser feita quando temos repetições de código em várias funções ou em vários arquivos, abstraímos esse código e depois só usaremos a chamada para ele.
Vamos ver na prática como isso funciona?

Um vira-tempo é um dispositivo mágico utilizado para viajar no tempo. Ele assemelha-se a uma ampulheta preza em um colar, sabemos que ele volta no tempo, mas não necessariamente o processo que ele leva para voltar ao tempo.

> "Eu marco as horas, cada uma, ainda nem ultrapassei o Sol. Meu uso e valor, para você, são medidos pelo o que você tem de fazer." - A inscrição gravada no vira tempo emprestado à Hermione Granger

Se colocássemos isso em código, ficaria assim:

![abstracao](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d1l2molew9065fwqcfr8.png)

Na classe _TimeTurner_, temos um método que faz a viagem no passado, nota-se que quando eu faço a instância da classe e acesso a sua função back_in_time, eu posso voltar ao passado sem saber como acontece debaixo dos panos.

{% embed https://gist.github.com/thaisribeiro/7c9aa252844ecb2346673b0d6c1eaa47 %}

#### Encapsulamento

Pode ser descrito como uma barreira protetora que impede que o código e os dados sejam acessados aleatoriamente por outro código definido fora da classe. O acesso aos dados e ao código é rigidamente controlado por uma classe.

![encapsulamento](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5gjhrg3usl8pyny29hsu.png)

Vamos entender melhor, suponha que eu tenho uma classe de DadosDoRh, essa classe lista as informações dos funcionários e também o salário de cada um. Contudo, salário é uma informação restrita, somente pessoas especificas do departamento pessoal, como isso ficaria?

```python
class DadosDoRh:
    def __init__(self, funcionario, departamento):
        self.funcionario = funcionario
        self.departamento = departamento
        self.salario = None
    def get_funcionario(self):
        return self.funcionario
    
    def __get_salario(self):
        if self.departamento == 'adm': 
            self.salario = 1000.00
        if self.departamento == 'dev':
            self.salario = 1250.00
        return self.salario
    def get_salario_by_user(self):
        if self.funcionario == 'adm' and self.departamento == 'adm':
            return self.__get_salario()
        else:
            return 'Você não tem permissão para ver o salário'
```
Observe que ___get_salario_ é uma função privada, em **python**, usamos o __ para garantir a restrição desse método, criamos uma regra também, que garante que esse método só pode ser "acessado" do lado de fora, a partir de outro método: _get_salario_by_user_ e somente por funcionários que atendam os requisitos da implementação.

Agora em HP, um exemplo claro de encapsulamento é a câmera secreta. Para quem está por fora da saga, é uma câmera subterrânea sob as masmorras da escola, criada na idade média por Salazar Sonserina. O lugar habita um monstro - basilisco - supostamente destinado a limpar a escola de todos os nascidos trouxas, ou seja, os que estavam na escola mas não tinha sangue bruxo.

A câmera poderia ser acessada somente por Salazar, mais tarde Harry Potter conseguiu acessá-la para salvar uma garota e a escola.

![encapsulamento](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/svxl79x0n7ap5o1y4x87.png)

{% embed https://gist.github.com/thaisribeiro/fb31679072efc61f45d85b2bff231a24 %}

#### Polimorfismo
Por fim, chegamos ao polimorfismo, que é a característica de poder atribuir um significado ou uso diferente a algo em diferentes contextos - especificamente, permitir que uma entidade como uma função ou um objeto tenha mais de uma forma.

Como assim?

Supondo que temos uma filial de lojas, e que os descontos a vista podem mudar entre uma e outra.

```python
class Desconto:
    def __init__(self, valor):
        self.valor = valor
    def calcula_desconto(self):
        return self.valor * 0.05
class DescontoLoja1(Desconto):
    def __init__(self, valor):
        super().__init__(valor)
    
    def calcula_desconto(self):
        return self.valor * 0.03
```
Observando o código acima, a minha loja 1 não aceita dar 5% de desconto a vista, ela dá 3%, mas o comportamento dela ainda se assemelha a classe base.

O que fizemos então? Sobrescrevemos o método calcula_desconto, para que atenda a nossa situação da loja 1, isso faz com que nosso objeto assuma uma nova forma dentro da segunda classe.

Uma ótima representação disso em Harry Potter é o bicho-papão, quando ele aparece na saga, ele não tem uma forma definida, ele assume a forma conforme o medo da pessoa.
Harry tem medo de dementador, então o bicho-papão assume a forma de um dementador e somente quando Harry domina a magia Riddikulus, é que ele consegue se livrar.

![polimorfismo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w89a50gfqi3fzpx5qss2.png)

{% embed https://gist.github.com/thaisribeiro/73f748df7de22728b4c4346609eb2906 %}

Antes de fecharmos o artigo, assim como fiz no fim do módulo, quero propor um desafio para vocês: Pensem em um filme, série, situação do dia a dia, livro, no que você pode implementar esses pilares, vai facilitar muito o entendimento do paradigma.

E para finalizar, deixo com vocês as implementações das minhas alunas, que foram incríveis e bastante criativas, para ajudá-los nesse processo. Até mais!

- https://github.com/lyacarolina/python-II/tree/construindocasa 

- https://github.com/MarcellaMenezes/entregasLuizaCode/tree/main/Atividade1
- https://github.com/palomasantos/classeesmalte/blob/main/esmalte.py
- https://github.com/CamiSenna/CamilaSenna/blob/main/ded_poo.py 
- https://github.com/lais-ches/Exercicios_Python/blob/main/Exercicio_Classes_Bleach.py
- https://github.com/anacarolcortez/LuizaCode/tree/main/aula_python/exercicios_extras_poo/mulheres_cientistas
- https://github.com/larissabertani/Luiza-Code-Python/blob/master/Testes/Python/classes.py
- https://github.com/rafawessling/LuizaCode/tree/main/Exemplo_POO
- https://github.com/mayaramatos/luizacode2/blob/mayara_branch/atividade2.py
- https://github.com/carmencmattos/orientacao-objetos