DEV Community

Cover image for Entendendo Programação Orientada a Objetos, de vez, com Harry Potter.
Thais Ribeiro
Thais Ribeiro

Posted on

10 1

Entendendo Programação Orientada a Objetos, de vez, com Harry Potter.

"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

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:

feedback carmen

feedback lilian

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.

Image description
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

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

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

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

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

class Witch:
def __init__(self, name, patron, house, color_eyes):
self.name = name
self.patron = patron
self.house = house
self.color_eyes = color_eyes
def get_name(self):
return f"O nome do(a) Bruxo(a) é: {self.name}"
def getHouse(self):
return f"Ele(a) está na casa {self.house}"
def getPatron(self):
return f"Seu patrono é {self.patron}"
class Harry(Witch):
def __init__(self, name, patron, house, color_eyes, type_witch):
self.type_witch = type_witch
super().__init__(name, patron, house, color_eyes)
def get_type_witch(self):
if self.type_witch == 'P':
return f"Este bruxo é sangue puro"
if self.type_witch == 'M':
return f"Este bruxo é Mestiço"
return f"Este é um trouxa*"
harry = Harry('Harry Potter', 'Cervo', 'Sonserina', 'Verde/Azul?', 'M')
print(harry.get_type_witch())
view raw heranca-poo.py hosted with ❤ by GitHub

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

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.

import time
class TimeTurner:
def __init__(self, skill, person):
self.skill = skill
self.person = person
def back_in_time(self):
start = time.time()
mensagem = f"Para {self.skill}, a {self.person}, "
mensagem += f"passou pela primeira camada do tempo em {time.time()}. "
time.sleep(3)
mensagem += f"Passou pela segunda camada do tempo em {time.time()}. "
time.sleep(5)
end = time.time()
calculo_tempo = end - start
return mensagem + f"E o tempo total gasto foi: {calculo_tempo}"
hermyone = TimeTurner('voltar ao tempo e salvar o Harry', 'Hermione')
# Voce nao precisa saber o que acontece por debaixo dos panos da função
print(hermyone.back_in_time())
view raw abstracao.py hosted with ❤ by GitHub

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

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'
Enter fullscreen mode Exit fullscreen mode

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

class Hogwarts:
def __init__(self, houses):
self.houses = houses
def get_houses(self):
msg_houses = ', '.join(self.houses)
return msg_houses
def __get_secret_access(self):
return "A camera secreta foi aberta!"
def access_secret_camera(self, witch):
if witch == "Harry":
return self.__get_secret_access()
return "Voce não tem acesso a esse local"
school = Hogwarts(['Grifinória', 'Lufa-Lufa', 'Sonserina', 'Corvinal'])
# school._get_secret_access()
# ERROR
access = school.access_secret_camera("Hermione")
print(access)
access = school.access_secret_camera("Harry")
print(access)
# Voce não tem acesso a esse local
# A camera secreta foi aberta!

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
Enter fullscreen mode Exit fullscreen mode

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

class Boogeyman:
def __init__(self):
pass
def form_boogeyman(self):
return 'Indefinida'
class FearHarry(Boogeyman):
def __init__(self, fear):
self.fear = fear
super().__init__()
def form_boogeyman(self):
return f"A forma do bicho-papão do Harry é: {self.fear}"
fear_harry = FearHarry("Dementador")
print(fear_harry.form_boogeyman())
view raw polimorfismo.py hosted with ❤ by GitHub

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!

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (1)

Collapse
 
freireigor profile image
Igor Freire

Awesome article! Parabéns pelo artigo..muito bem escrito e ensinado..
Congrats for your article.

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay