Entendendo Programação Orientada a Objetos, de vez, com Harry Potter.
Thais Ribeiro
Posted on September 13, 2022
"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.
Oi pessoALL, agora sim, tudo bem com vocês? Atualmente, sou professora no Luiza, 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:
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 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.
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.
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.
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.
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.
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.
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:
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.
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.
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?
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.
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.
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.
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/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
Posted on September 13, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.