Os quatro pilares da Programação Orientada a Objetos são conceitos fundamentais que guiam o design de sistemas baseados em objetos.
_
para atributos "protegidos" e __
para "privados") do que por imposição estrita da linguagem.class ContaBancaria:
def __init__(self, saldo_inicial):
self.__saldo = saldo_inicial # Atributo "privado" por convenção
def depositar(self, valor):
if valor > 0:
self.__saldo += valor
print(f"Depósito de R${valor:.2f} realizado. Novo saldo: R${self.__saldo:.2f}")
else:
print("O valor do depósito deve ser positivo.")
def sacar(self, valor):
if valor > 0 and self.__saldo >= valor:
self.__saldo -= valor
print(f"Saque de R${valor:.2f} realizado. Novo saldo: R${self.__saldo:.2f}")
else:
print("Saldo insuficiente ou valor de saque inválido.")
def get_saldo(self): # Método público para acessar o saldo
return self.__saldo
minha_conta = ContaBancaria(1000)
minha_conta.depositar(200) # Saída: Depósito de R$200.00 realizado. Novo saldo: R$1200.00
minha_conta.sacar(150) # Saída: Saque de R$150.00 realizado. Novo saldo: R$1050.00
# print(minha_conta.__saldo) # Isso causaria um AttributeError (acesso direto ao "privado")
print(minha_conta.get_saldo()) # Saída: 1050.0
Cachorro
é um tipo de Animal
).Pythonclass Animal:
def __init__(self, nome):
self.nome = nome
def comer(self):
print(f"{self.nome} está comendo.")
class Cachorro(Animal): # Cachorro herda de Animal
def __init__(self, nome, raca):
super().__init__(nome) # Chama o construtor da classe pai
self.raca = raca
def latir(self):
print(f"{self.nome} da raça {self.raca} está latindo: Au Au!")
meu_cachorro = Cachorro("Buddy", "Golden Retriever")
meu_cachorro.comer() # Saída: Buddy está comendo. (Método herdado)
meu_cachorro.latir() # Saída: Buddy da raça Golden Retriever está latindo: Au Au!
Polimorfismo: Significa "muitas formas". Em POO, refere-se à capacidade de objetos de diferentes classes responderem ao mesmo método de maneiras diferentes. Herança e interfaces (em outras linguagens) são a base para o polimorfismo. Em Python, o polimorfismo é natural devido à tipagem dinâmica (Duck Typing: "Se parece com um pato, nada como um pato e grasna como um pato, então provavelmente é um pato").
class Pato:
def voar(self):
print("Pato está voando.")
def fazer_som(self):
print("Quack!")
class Aviao:
def voar(self):
print("Avião está voando alto.")
def fazer_som(self):
print("Ruído de motor!")
def fazer_voar_e_som(objeto):
objeto.voar()
objeto.fazer_som()
pato = Pato()
aviao = Aviao()
fazer_voar_e_som(pato)
# Saída:
# Pato está voando.
# Quack!
fazer_voar_e_som(aviao)
# Saída:
# Avião está voando alto.
# Ruído de motor!
Abstração: Foca em mostrar apenas as informações essenciais e esconder os detalhes complexos de implementação. Define o que um objeto deve fazer, sem especificar como ele faz. Em Python, a abstração pode ser alcançada usando classes abstratas e métodos abstratos do módulo abc
.Python
from abc import ABC, abstractmethod
class FormaGeometrica(ABC): # Classe abstrata
@abstractmethod
def calcular_area(self):
pass # Método abstrato, deve ser implementado pelas subclasses
@abstractmethod
def calcular_perimetro(self):
pass
class Retangulo(FormaGeometrica):
def __init__(self, largura, altura):
self.largura = largura
self.altura = altura
def calcular_area(self):
return self.largura * self.altura
def calcular_perimetro(self):
return 2 * (self.largura + self.altura)
# forma = FormaGeometrica() # Isso daria um erro, não se pode instanciar classes abstratas
ret = Retangulo(5, 10)
print(f"Área do Retângulo: {ret.calcular_area()}") # Saída: Área do Retângulo: 50
print(f"Perímetro do Retângulo: {ret.calcular_perimetro()}") # Saída: Perímetro do R