Seja muito bem-vindo à Academy Code Christ!
🌍 Academy Code Christ está disponível em vários idiomas.Fique à vontade para usar o tradutor na Barra lateral (Sidebar) e aprender no seu idioma.
Python 🐍 Etapa 10
Programação Orientada a Objetos
🎯 Por que aprender Programação Orientada a Objetos?
Até agora, você escreveu código de maneira estruturada: criou funções, manipulou dados, agrupou em módulos.
Mas conforme o projeto cresce, isso começa a ficar complicado de gerenciar — especialmente se muitas variáveis e funções dependem umas das outras.
A Programação Orientada a Objetos ajuda a organizar o código de forma natural, semelhante ao mundo real.
Exemplo: você pode representar um aluno, um carro ou uma conta bancária — cada um com seus atributos (dados) e métodos (ações).
Isso traz grandes vantagens:
● 🔹 Reutilização de código (herança, classes genéricas)
● 🔹 Organização e clareza
● 🔹 Facilidade de manutenção e expansão
● 🔹 Representação intuitiva de entidades reais
Conceitos básicos
|
Conceito |
Descrição |
|
Classe |
É o modelo ou a forma que define as características e comportamentos de um objeto. |
|
Objeto |
É uma instância (exemplo concreto) de uma classe. |
|
Atributos |
São as variáveis que pertencem a uma classe/objeto (características). |
|
Métodos |
São funções definidas dentro da classe (comportamentos). |
|
Encapsulamento |
Técnica que protege os dados internos de uma classe. |
|
Herança |
Permite que uma classe “filha” herde atributos e métodos de uma “classe pai”. |
|
Polimorfismo |
Permite que métodos com o mesmo nome tenham comportamentos diferentes. |
Vamos ver cada um desses conceitos na prática.
Criando sua primeira classe
def __init__(self, nome, idade):
self.nome = nome
self.idade = idade
def apresentar(self):
print(f"Olá! Meu nome é {self.nome} e tenho {self.idade} anos.")
Como funciona:
● class Pessoa: → cria uma nova classe chamada Pessoa.
● __init__ → é o método construtor, executado automaticamente ao criar um novo objeto.
● self → é uma referência ao próprio objeto.
● Os parâmetros (nome, idade) são recebidos e armazenados como atributos.
Criando objetos (instâncias):
p1 = Pessoa("Ana", 25)
p2 = Pessoa("Bruno", 30)
p1.apresentar()
p2.apresentar()
Saída:
Olá! Meu nome é Ana e tenho 25 anos.
Olá! Meu nome é Bruno e tenho 30 anos.
Entendendo self
O self é
uma palavra obrigatória em métodos de classe e representa a própria
instância.
É o elo entre os atributos e os métodos
do objeto.
class Carro:
def __init__(self, modelo):
self.modelo = modelo
def mostrar_modelo(self):
print("O modelo do carro é:", self.modelo)
Cada objeto armazena seus próprios dados e acessa-os com self.
Atributos de instância e de classe
Nem todos os atributos precisam ser únicos por objeto.
Podemos ter variáveis que pertencem à
classe toda.
class Aluno:
escola = "Python Academy" # atributo da classe
def __init__(self, nome):
self.nome = nome # atributo da instância
a1 = Aluno("Carla")
a2 = Aluno("Lucas")
print(a1.nome, "-", a1.escola)
print(a2.nome, "-", a2.escola)
Saída:
Carla - Python Academy
Lucas - Python Academy
Se mudar Aluno.escola, o valor é alterado para todos.
Métodos de instância, classe e estáticos
1️⃣ Método de instância: age sobre o próprio objeto.
def metodo(self): ...
2️⃣ Método de classe: age sobre a classe inteira, e não sobre um objeto específico. É definido com @classmethod.
class Empresa:
funcionarios = 0
@classmethod
def contratar(cls):
cls.funcionarios += 1
3️⃣ Método estático: é uma função dentro da classe, que não acessa o estado da classe nem do objeto. Usa o decorador @staticmethod.
class Matematica:
@staticmethod
def dobro(x):
return x * 2
print(Matematica.dobro(5))
Saída:
10
Encapsulamento: protegendo dados
Encapsular significa ocultar os detalhes internos do objeto, expondo apenas o necessário.
Níveis de acesso:
|
Prefixo |
Nome exemplo |
Descrição |
|
Público |
self.nome |
acessível de qualquer lugar |
|
Protegido |
self._idade |
convenção: acesso restrito a subclasses |
|
Privado |
self.__senha |
acesso apenas dentro da própria classe |
Exemplo:
class ContaBancaria:
def __init__(self, titular, saldo):
self.titular = titular
self.__saldo = saldo # privado
def depositar(self, valor):
self.__saldo += valor
def exibir_saldo(self):
print(f"Saldo atual: R${self.__saldo}")
conta = ContaBancaria("Ana", 500)
conta.depositar(200)
conta.exibir_saldo()
Saída:
Saldo atual: R$700
Qualquer tentativa de acessar conta.__saldo gerará erro — o dado está protegido.
Usando getters e setters
Para acessar ou alterar atributos privados de forma controlada, usamos métodos:
class Produto:
def __init__(self, nome, preco):
self.__nome = nome
self.__preco = preco
def get_preco(self):
return self.__preco
def set_preco(self, novo_preco):
if novo_preco >= 0:
self.__preco = novo_preco
else:
print("Erro: preço inválido.")
p = Produto("Camiseta", 50)
print(p.get_preco())
p.set_preco(-10)
Herança: reaproveitando código
A herança permite que uma classe filha herde atributos e métodos de uma classe pai.
class Pessoa:
def __init__(self, nome):
self.nome = nome
def falar(self):
print(f"{self.nome} está falando...")
class Estudante(Pessoa):
def estudar(self):
print(f"{self.nome} está estudando.")
e = Estudante("Lucas")
e.falar()
e.estudar()
Saída:
Lucas está falando...
Lucas está estudando.
A classe filha (Estudante) herda tudo que existe na classe Pessoa, podendo adicionar novos comportamentos.
Usando super() para aproveitar o
construtor da classe pai
Quando a classe filha redefine o __init__, podemos chamar o construtor da classe pai com super().
class Funcionario(Pessoa):
def __init__(self, nome, salario):
super().__init__(nome) # chama o construtor da classe Pessoa
self.salario = salario
def exibir_dados(self):
print(f"{self.nome} ganha R${self.salario}")
f = Funcionario("Maria", 3500)
f.exibir_dados()
Comportamento polimórfico
Polimorfismo significa “múltiplas formas” — ou seja, diferentes classes podem ter métodos com o mesmo nome, mas comportamentos distintos.
class Animal:
def som(self):
print("Som genérico de animal")
class Cachorro(Animal):
def som(self):
print("Au Au!")
class Gato(Animal):
def som(self):
print("Miau!")
animais = [Cachorro(), Gato(), Animal()]
for a in animais:
a.som()
Saída:
Au Au!
Miau!
Som genérico de animal
Cada objeto responde de forma diferente ao mesmo método — isso é polimorfismo em ação.
Classes abstratas
Classes que servem apenas como modelo para outras.
Usamos o módulo abc (Abstract Base Class).
from abc import ABC, abstractmethod
class Forma(ABC):
@abstractmethod
def area(self):
pass
Agora, qualquer classe filha precisa obrigatoriamente implementar area():
class Quadrado(Forma):
def __init__(self, lado):
self.lado = lado
def area(self):
return self.lado ** 2
q = Quadrado(4)
print(q.area()) # 16
Tentar instanciar Forma() diretamente dá erro — é uma classe abstrata.
Composição: “tem um”
Enquanto a herança representa um “é um”, a composição representa um “tem um”.
class Motor:
def __init__(self, potencia):
self.potencia = potencia
class Carro:
def __init__(self, modelo, potencia):
self.modelo = modelo
self.motor = Motor(potencia) # carro TEM um motor
c = Carro("Sedan", 120)
print(f"O carro {c.modelo} tem motor de {c.motor.potencia}cv.")
Saída:
O carro Sedan tem motor de 120cv.
Reescrevendo representações: __str__ e __repr__
Esses métodos especiais definem como um objeto aparece ao ser impresso.
class Pessoa:
def __init__(self, nome, idade):
self.nome = nome
self.idade = idade
def __str__(self):
return f"{self.nome}, {self.idade} anos"
p = Pessoa("Ana", 28)
print(p)
Saída:
Ana, 28 anos
Mini‑projeto prático: Sistema de cadastro e conta bancária
class Pessoa:
def __init__(self, nome, cpf):
self.nome = nome
self.cpf = cpf
class Conta:
def __init__(self, titular, saldo=0):
self.titular = titular
self.__saldo = saldo
def depositar(self, valor):
if valor > 0:
self.__saldo += valor
print(f"Depósito de R${valor} realizado.")
else:
print("Valor inválido.")
def sacar(self, valor):
if 0 < valor <= self.__saldo:
self.__saldo -= valor
print(f"Saque de R${valor} concluído.")
else:
print("Saldo insuficiente.")
def extrato(self):
print(f"Titular: {self.titular.nome} | Saldo: R${self.__saldo}")
# Criando cliente e conta
cliente1 = Pessoa("Lucas", "123.456.789-00")
conta1 = Conta(cliente1, 1000)
conta1.depositar(250)
conta1.sacar(500)
conta1.extrato()
Saída:
Depósito de R$250 realizado.
Saque de R$500 concluído.
Titular: Lucas | Saldo: R$750
Esse código aplica encapsulamento, composição, métodos, atributos e instâncias reais. Tudo o que torna um sistema realista e orientado a objetos.
Boas práticas em POO
🔹 Nomeie classes com letra maiúscula (ex: Cliente, Produto).
🔹 Deixe cada classe com uma
responsabilidade clara.
🔹 Prefira herança apenas quando
houver relação direta entre classes — do contrário, use composição.
🔹 Use encapsulamento e
propriedades para proteger dados.
🔹 Documente suas classes com docstrings
explicando o propósito e os métodos.
🔹 Abuse da reutilização e evite
repetição de código (Don’t Repeat Yourself – DRY).
Resumo do capítulo
Nesta etapa, você aprendeu a:
✅ Criar
e instanciar classes e objetos.
✅ Definir atributos e métodos próprios.
✅ Entender encapsulamento,
getters, setters
e diferentes níveis de acesso.
✅ Aplicar herança, super,
polimorfismo e composição.
✅ Utilizar classes abstratas, métodos especiais e boas
práticas.
✅ Construir um sistema completo seguindo
o paradigma orientado a objetos.
A partir de agora, você tem em mãos todo o poder da POO em Python — o mesmo estilo usado em frameworks e sistemas profissionais.
🎯 Na próxima etapa, entraremos no mundo da manipulação de arquivos e dados externos — onde você vai aprender a ler, gravar e processar informações armazenadas em disco, interagindo com o ambiente real.

%20-%20Copia.png)
.png)
.png)
.png)
Postar um comentário