O Que Você Vai Aprender
Nesta seção de exercícios, você aplicará os conceitos de classes abstratas e polimorfismo para criar um sistema de armas e demonstrar como diferentes tipos de armas podem ser tratados de forma uniforme através de uma interface comum.
📝 Criar Classes Abstratas
Definir um "contrato" de comportamento para as subclasses.
🔄 Implementar Polimorfismo
Demonstrar como objetos de diferentes classes podem responder ao mesmo método de forma única.
Desafios Propostos
Siga os passos abaixo para construir a hierarquia de classes de armas, implementando abstração e polimorfismo.
-
✓
1. Crie uma classe abstrata `Arma`
Com um método abstrato `atacar()`.
from abc import ABC, abstractmethod class Arma(ABC): def __init__(self, nome): self.nome = nome @abstractmethod def atacar(self): pass
-
✓
2. Crie subclasses `Espada` e `Arco`
Ambas devem herdar de `Arma` e implementar o método `atacar()` de maneiras diferentes.
class Espada(Arma): def __init__(self, nome, dano_base): super().__init__(nome) self.dano_base = dano_base def atacar(self): return f"A {self.nome} causa {self.dano_base} de dano com um golpe cortante!" class Arco(Arma): def __init__(self, nome, tipo_flecha): super().__init__(nome) self.tipo_flecha = tipo_flecha def atacar(self): return f"O {self.nome} dispara uma flecha ({self.tipo_flecha}) com precisão!"
-
✓
3. Crie uma função `lutar()`
Que chame `arma.atacar()`, demonstrando o polimorfismo.
def lutar(personagem, arma): print(f"{personagem} usa a {arma.nome} para atacar:") print(arma.atacar()) # Exemplo de uso: # espada_longa = Espada("Espada Longa", 15) # arco_curto = Arco("Arco Curto", "fogo") # lutar("Cavaleiro", espada_longa) # lutar("Arqueiro", arco_curto)
Simulador: Sistema de Armas Polimórfico
Crie diferentes armas e um personagem para lutar com elas. Observe como a função `lutar` chama o método `atacar` de forma polimórfica, adaptando-se ao tipo de arma.
Classes `Arma`, `Espada` e `Arco` (simuladas)
As classes e a função `lutar` foram implementadas para simular o comportamento de abstração e polimorfismo em Python, permitindo interações em tempo real.
# Simulação de classes abstratas em Python
from abc import ABC, abstractmethod
# Classe Abstrata: Arma
class Arma(ABC):
"""
Classe abstrata que serve como um "contrato" para todas as armas.
Não pode ser instanciada diretamente.
"""
def __init__(self, nome: str):
self.nome = nome
@abstractmethod
def atacar(self) -> str:
"""
Método que toda subclasse de Arma é obrigada a implementar.
"""
pass
# Subclasse: Espada
class Espada(Arma):
"""
Uma implementação concreta de Arma.
"""
def __init__(self, nome: str, dano_base: int):
super().__init__(nome) # Chama o construtor da classe pai (Arma)
self.dano_base = dano_base
def atacar(self) -> str:
# Implementação específica do ataque para a Espada
return f"A {self.nome} causa {self.dano_base} de dano com um golpe cortante!"
# Subclasse: Arco
class Arco(Arma):
"""
Outra implementação concreta de Arma.
"""
def __init__(self, nome: str, tipo_flecha: str):
super().__init__(nome)
self.tipo_flecha = tipo_flecha
def atacar(self) -> str:
# Implementação específica do ataque para o Arco
return f"O {self.nome} dispara uma flecha ({self.tipo_flecha}) com precisão!"
# Função polimórfica
def lutar(personagem: str, arma: Arma):
"""
Esta função funciona com qualquer objeto que seja uma subclasse de Arma,
demonstrando o polimorfismo.
"""
print(f"{personagem} usa a {arma.nome} para atacar:")
print(arma.atacar())
print("-" * 20)
# --- Demonstração de uso ---
# 1. Criando instâncias das classes concretas
espada_longa = Espada("Espada Longa de Aço", 15)
arco_elfico = Arco("Arco Élfico", "Flecha de Prata")
# 2. Usando a função polimórfica com diferentes tipos de armas
guerreiro = "Aragorn"
elfo = "Legolas"
lutar(guerreiro, espada_longa)
lutar(elfo, arco_elfico)
# 3. Tentando instanciar a classe abstrata (irá gerar um erro)
try:
arma_generica = Arma("Arma Genérica")
except TypeError as e:
print("\nTentativa de instanciar a classe abstrata:")
print(f"ERRO: {e}")
Criar Armas e Lutar
Desafios para Continuar
Coloque seus conhecimentos em prática com estes desafios para solidificar sua compreensão sobre classes abstratas e polimorfismo.
-
✓
1. Adicionar uma nova arma
Crie uma nova subclasse de `Arma`, por exemplo, `CajadoMagico`, que implemente o método `atacar()` de uma maneira totalmente nova (ex: "lança um feitiço de bola de fogo").
-
✓
2. Exibir características específicas
Modifique a função `lutar()` para que, além de chamar `arma.atacar()`, ela também tente exibir uma característica específica da arma se ela existir (ex: `arma.dano_base` para espada, `arma.tipo_flecha` para arco, usando `hasattr()` para verificar).