Classes e Métodos Abstratos
Parte da seção Object Oriented Programming do Journey de Python da Coddy — lição 25 de 64.
Classes abstratas são classes que não podem ser instanciadas diretamente e contêm métodos abstratos que devem ser implementados por subclasses.
Pense nisso como um formulário: Uma classe abstrata é como um código de formulário obrigatório onde alguns campos são exigidos (métodos abstratos) e outros são opcionais (métodos concretos). Você não pode enviar o formulário em si - você deve preencher todos os campos obrigatórios primeiro. Da mesma forma, você não pode criar instâncias de uma classe abstrata até que todos os métodos abstratos sejam implementados em uma subclasse.
Importe o módulo abc para criar classes abstratas:
from abc import ABC, abstractmethodCrie uma classe abstrata com métodos abstratos:
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
def describe(self):
return "This is a shape" # Método concreto (possui implementação)O decorador @abstractmethod marca métodos que devem ser implementados por subclasses - estes são os "campos obrigatórios" no seu formulário. Métodos regulares como describe() podem ter implementações e são herdados como estão - estes são os "campos pré-preenchidos".
Por que usar classes abstratas? Elas impõem um contrato. Se você criar uma classe Shape, você está dizendo "toda forma DEVE ser capaz de calcular sua área e perímetro". Isso evita bugs onde você pode esquecer de implementar métodos críticos.
Tente criar uma instância da classe abstrata:
# Isso causará um erro:
# shape = Shape() # TypeError: Não é possível instanciar a classe abstrataEste erro é intencional - é como tentar enviar um formulário vazio. O Python está dizendo "Você ainda não preencheu os campos obrigatórios (métodos area e perimeter)!"
Crie uma subclasse concreta que implemente todos os métodos abstratos:
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
def perimeter(self):
return 2 * 3.14 * self.radiusAgora nós "preenchemos todos os campos obrigatórios" - implementamos tanto area() quanto perimeter(). A classe Circle agora é uma classe concreta completa que pode ser instanciada.
Agora você pode criar instâncias da classe concreta:
circle = Circle(5)
print(circle.area())
print(circle.perimeter())
print(circle.describe()) # Método concreto herdadoCrie outra subclasse concreta:
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width self.height
def perimeter(self):
return 2 * (self.width + self.height)
rectangle = Rectangle(4, 6)
print(rectangle.area())
print(rectangle.perimeter())Saída:
78.5
31.400000000000002
This is a shape
24
20Classes abstratas definem um contrato que as subclasses devem seguir. Use ABC e @abstractmethod para criar classes abstratas. As subclasses devem implementar todos os métodos abstratos ou elas também serão abstratas. Isso garante consistência e evita implementações incompletas.
Desafio
MédioNeste desafio, você implementará um sistema de processamento de pagamentos.
Você precisa completar a implementação nestes arquivos:
paymentmethod.py- Classe base abstrata com lógica de validaçãocreditcard.py- Implementação de pagamento por cartão de créditopaypal.py- Implementação de pagamento por PayPal
Siga os comentários TODO em cada arquivo para implementar a funcionalidade necessária. Os comentários o guiarão passo a passo na criação de métodos abstratos, na implementação de subclasses concretas e no estabelecimento de relações de importação adequadas entre os arquivos.
O arquivo driver.py contém casos de teste que verificarão se sua implementação funciona corretamente, processando diferentes cenários de pagamento e exibindo os detalhes apropriados para cada método de pagamento.
Folha de consulta
Classes abstratas não podem ser instanciadas diretamente e contêm métodos abstratos que devem ser implementados por subclasses.
Importe o módulo abc:
from abc import ABC, abstractmethodCrie uma classe abstrata com métodos abstratos:
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
def describe(self):
return "This is a shape" # Método concreto (possui implementação)O decorador @abstractmethod marca métodos que devem ser implementados por subclasses. Métodos regulares podem ter implementações.
Classes abstratas não podem ser instanciadas:
# Isso causará um erro:
# shape = Shape() # TypeError: Can't instantiate abstract classCrie subclasses concretas que implementem todos os métodos abstratos:
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
def perimeter(self):
return 2 * 3.14 * self.radius
circle = Circle(5)
print(circle.area()) # 78.5
print(circle.describe()) # Método concreto herdadoPonto Chave: Classes abstratas definem um modelo que as subclasses devem seguir. As subclasses devem implementar todos os métodos abstratos ou também serão abstratas.
Experimente você mesmo
from creditcard import CreditCard
from paypal import PayPal
# Teste as implementações - NÃO MODIFIQUE ESTE CÓDIGO DE TESTE
cc = CreditCard("1234567890123456")
pp = PayPal("user@example.com")
# Processar pagamentos válidos
if cc.validate(100):
print(cc.process_payment(100))
print(cc.payment_details())
if pp.validate(200):
print(pp.process_payment(200))
print(pp.payment_details())
# Tentar um valor inválido
if not pp.validate(0):
print("Invalid payment amount")
# Isso geraria um erro se fosse descomentado:
# pm = PaymentMethod() # Não é possível instanciar uma classe abstrataEsta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Object Oriented Programming
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosO Parâmetro selfMétodosAtributosMétodo Construtor (__init__)Recapitulação - Calculadora Simples4Herança
Herança BásicaA Função super()Sobrescrita de MétodoHerança MúltiplaOrdem de Resolução de MétodosRecapitulação - Hierarquia de Funcionários7Métodos Especiais
Introdução aos Métodos MágicosSobrecarga de OperadoresMétodos Mágicos de ContêinerRecapitulação - Lista Personalizada10Padrões de Projeto Parte 1
Introdução a Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão Strategy2Decoradores
Introdução aos DecoradoresDecorador de PropriedadeDecorador de Método EstáticoDecorador de Método de Classe5Polimorfismo
Sobrescrita de Método RevisitadaDuck TypingClasses e Métodos AbstratosDesign de InterfacesRecapitulação - Calculadora de Formas8Conceitos Avançados de POO
Composição vs HerançaMixinsMétodos Estáticos e de ClasseDecoradores de ClasseGerenciadores de Contexto11Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite3Propriedades de Classe
Variáveis de Instância vs de ClasseDecoradores de PropriedadeAtributos PrivadosRecapitulação - Gerenciador de Conta Bancária6Encapsulamento
Membros Públicos, Protegidos e PrivadosModificadores de AcessoOcultação de InformaçãoProperty Decorators AvançadosRecapitulação - Sistema de Registro de Alunos12Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses Livro e Usuário