Menu
CoddyTech

Classes e Métodos Abstratos

Parte da seção Programação Orientada a Objetos 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 modelo obrigatório de formulário em que alguns campos são obrigatórios (métodos abstratos) e outros são opcionais (métodos concretos). Você não pode enviar o formulário em si — primeiro precisa preencher todos os campos obrigatórios. 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, abstractmethod

Crie 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 (tem implementação)

O decorador @abstractmethod marca métodos que devem ser implementados pelas subclasses — esses são os “campos obrigatórios” do seu formulário. Métodos comuns como describe() podem ter implementações e ser herdados como estão — esses são os “campos preenchidos previamente”.

Por que usar classes abstratas? Elas impõem um contrato. Se você criar uma classe Shape, estará dizendo: “toda forma DEVE ser capaz de calcular sua área e seu perímetro”. Isso evita bugs que podem surgir quando você se esquece de implementar métodos essenciais.

Tente criar uma instância da classe abstrata:

# Isso causará um erro:
# shape = Shape()  # TypeError: Não é possível instanciar uma classe abstrata

Esse erro é intencional — é como tentar enviar um formulário vazio. 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.radius

Agora, "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 herdado

Crie 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
20

Classes 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 também serão abstratas. Isso garante consistência e evita implementações incompletas.

challenge icon

Desafio

Médio

Neste desafio, você vai implementar um sistema de processamento de pagamentos.

Você precisa concluir a implementação nestes arquivos:

  • paymentmethod.py - Classe base abstrata com lógica de validação
  • creditcard.py - Implementação de pagamento com cartão de crédito
  • paypal.py - Implementação de pagamento com PayPal

Siga os comentários TODO em cada arquivo para implementar a funcionalidade necessária. Os comentários vão guiar você passo a passo na criação de métodos abstratos, na implementação de subclasses concretas e no estabelecimento das 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.

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")

# Processe 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())

# Teste 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 abstrata
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de Python online