Herança na Programação Orientada a Objetos (POO)
Aprendendo herança em Python com exemplos de jogos
1. O que é herança?
A herança é um dos principais conceitos da Programação Orientada a Objetos (POO). Ela permite que uma classe aproveite atributos e métodos de outra classe, evitando a repetição de código.
Esse conceito é muito utilizado no desenvolvimento de jogos, pois diferentes personagens podem compartilhar características e habilidades.
Imagine um jogo de aventura com três tipos de personagens: Guerreiro, Mago e Arqueiro. Todos possuem nome, vida e podem atacar, mas cada um também possui habilidades próprias.
Guerreiro
Mago
Arqueiro
Em vez de repetir o mesmo código para cada personagem, podemos criar uma classe principal chamada Personagem e fazer as outras classes herdarem suas características.
Na herança, utilizamos dois conceitos:
- Classe-pai (superclasse): fornece os atributos e métodos que podem ser herdados.
- Classe-filha (subclasse): herda características da classe-pai e pode acrescentar novas funcionalidades.
2. Como funciona a herança em Python?
Em Python, indicamos a herança colocando o nome da classe-pai entre parênteses na declaração da classe-filha.

Nesse exemplo, Guerreiro é uma classe-filha de Personagem.

As três classes herdam de Personagem.
3. Exemplo 1 – Herança simples em um jogo
Vamos criar uma classe Personagem com um método chamado mover(). Em seguida, criaremos uma classe Guerreiro que herdará esse método.


Saída do programa:
O personagem está andando.
O guerreiro atacou com a espada!
Explicação: A classe Guerreiro não possui o método mover() declarado diretamente. Entretanto, consegue executá-lo porque herdou esse método da classe Personagem.
Já o método usarEspada() pertence especificamente à classe Guerreiro.
4. Exemplo 2 – Herdando atributos e métodos
Em um jogo, diferentes personagens podem possuir atributos em comum, como nome, vida e força.
Vamos criar uma classe Personagem com esses atributos e utilizar o método especial __init__() para inicializá-los.


Saída do programa:
Nome: Arthur
Vida: 100
Arthur atacou com a espada!
Nome: Merlin
Vida: 80
Merlin lançou uma bola de fogo!
Observe: As classes Guerreiro e Mago herdam os atributos nome e vida, além do método mostrarStatus().
Cada classe também possui suas habilidades específicas.
5. Adicionando novos atributos com super()
Imagine que nosso jogo possui um guerreiro que utiliza força e um mago que utiliza mana.
Esses atributos são específicos de cada tipo de personagem.
Para acrescentá-los, podemos utilizar super(), que permite chamar métodos herdados, como o inicializador da classe-pai.

Assim, conseguimos aproveitar o código da classe-pai e acrescentar novas características.
6. Exemplo 4 – Sobrescrita de métodos
A sobrescrita de métodos acontece quando uma classe-filha cria sua própria versão de um método que já existe na classe-pai.
Imagine que todos os personagens de um jogo podem atacar, mas cada um utiliza um tipo diferente de ataque.


Saída do programa:
Ataque com espada!
Ataque com flecha!
Nesse exemplo, as três classes sobrescrevem o método atacar() da classe Personagem.
Isso também demonstra o conceito de polimorfismo, pois um mesmo método pode apresentar comportamentos diferentes dependendo do objeto que o executa.
7. Exemplo 5 – Criando um pequeno sistema de batalha
Agora vamos reunir os conceitos estudados em um exemplo mais próximo de um jogo.
Teremos dois personagens que podem atacar e receber dano. O guerreiro também poderá executar um ataque especial.


Saída do programa:
Arthur atacou com a espada!
Merlin ficou com 60 de vida.
Merlin lançou uma magia!
Arthur ficou com 85 de vida.
Nesse exemplo, o método receberDano() foi declarado apenas uma vez, na classe Personagem, mas é utilizado pelos dois tipos de personagens.
Essa é uma das principais vantagens da herança: reaproveitar código para diferentes objetos do jogo.
8. Vantagens da herança no desenvolvimento de jogos
A herança oferece diversas vantagens:
- Reaproveitamento de código: diferentes personagens podem utilizar os mesmos métodos.
- Organização: facilita a criação de personagens, inimigos e outros elementos.
- Manutenção: permite modificar comportamentos compartilhados sem alterar todas as classes-filhas.
- Expansão: facilita a criação de novos personagens com habilidades próprias.
É importante lembrar que nem toda relação entre elementos de um jogo deve utilizar herança. Por exemplo, um guerreiro possui uma espada, mas não é uma espada. Nesse caso, normalmente é mais adequado utilizar um objeto de arma associado ao personagem.
Atividade de Fixação – POO
QUESTÃO 1
Qual é a principal vantagem da herança ao desenvolver personagens de um jogo?
A) Impedir a criação de novos personagens.
B) Permitir que diferentes classes reutilizem atributos e métodos.
C) Eliminar a necessidade de utilizar objetos.
D) Fazer todos os personagens terem exatamente as mesmas habilidades.
QUESTÃO 2
No código class Mago(Personagem):, o que representa Personagem?
A) Um método.
B) Um objeto.
C) A classe-pai.
D) Um atributo.
QUESTÃO 3
Um Guerreiro herda o método mover() da classe Personagem. O que acontece quando executamos guerreiro.mover()?
A) O método herdado pode ser executado pelo objeto Guerreiro.
B) O Python apresenta erro obrigatoriamente.
C) O método é removido da classe-pai.
D) Uma nova classe é criada automaticamente.
QUESTÃO 4
Qual é a finalidade de super().__init__() em uma classe-filha?
A) Apagar a classe-pai.
B) Criar um novo objeto automaticamente.
C) Impedir a criação de novos atributos.
D) Reutilizar a inicialização herdada da classe-pai.
QUESTÃO 5
As classes Guerreiro e Mago possuem versões diferentes do método atacar(). Como é chamada essa técnica?
A) Criação de atributos.
B) Sobrescrita de métodos.
C) Herança múltipla obrigatória.
D) Exclusão de métodos.