Universo DC - Aprenda POO com exemplos práticos
Entender o conceito de Polimorfismo e como objetos de diferentes classes podem ser tratados de forma uniforme.
// TÓPICO: Polimorfismo com Classe Base
// Podemos colocar objetos de classes diferentes em uma lista da classe base
List<Personagem> personagens = new List<Personagem>();
// Adicionando heróis e vilões (objetos diferentes)
personagens.Add(new Heroi("Batman", 85, "Liga da Justiça"));
personagens.Add(new Heroi("Superman", 100, "Liga da Justiça"));
personagens.Add(new Heroi("Flash", 90, "Liga da Justiça"));
personagens.Add(new Vilao("Coringa", 80, "Legião do Mal"));
personagens.Add(new Vilao("Lex Luthor", 75, "Legião do Mal"));
personagens.Add(new Vilao("Darkseid", 95, "Apokolips"));
// TÓPICO: Polimorfismo em Ação
// Cada objeto chama sua própria implementação do método
foreach (Personagem personagem in personagens)
{
// Mesmo método, comportamentos diferentes!
personagem.Apresentar(); // Cada um se apresenta de forma diferente
personagem.UsarPoder(); // Cada um usa poder de forma diferente
Console.WriteLine();
}
Saída Esperada:
Olá! Eu sou Batman, herói da Liga da Justiça, nível 85!
Batman usa seu poder para proteger os inocentes!
Olá! Eu sou Superman, herói da Liga da Justiça, nível 100!
Superman usa seu poder para proteger os inocentes!
Cuidado! Eu sou Coringa, vilão da Legião do Mal, nível 80!
Coringa usa seu poder para causar caos e destruição!
// TÓPICO: Polimorfismo com Interface
// Objetos diferentes que implementam a mesma interface
List<IVoador> voadores = new List<IVoador>();
// Criando objetos diferentes que voam
Heroi superman = new Heroi("Superman", 100, "Liga da Justiça");
superman.AltitudeMaxima = 10000;
Heroi mulherMaravilha = new Heroi("Mulher Maravilha", 95, "Liga da Justiça");
mulherMaravilha.AltitudeMaxima = 5000;
// Adicionando à lista (tratados como IVoador)
voadores.Add(superman);
voadores.Add(mulherMaravilha);
// TÓPICO: Polimorfismo através da Interface
// Todos voam, mas cada um pode ter implementação diferente
foreach (IVoador voador in voadores)
{
voador.Voar(); // Cada um voa de sua forma
voador.Pousar(); // Cada um pousa de sua forma
Console.WriteLine();
}
// Na classe base Personagem
public virtual void Descansar()
{
Console.WriteLine($"{Nome} está descansando...");
}
// Na classe Heroi (pode sobrescrever ou não)
public override void Descansar()
{
Console.WriteLine($"{Nome} descansa na Batcaverna...");
}
// Na classe Vilao (usa a implementação padrão ou sobrescreve)
// Se não sobrescrever, usa a de Personagem
// Na classe base Personagem (abstrata)
public abstract void UsarPoder(); // Sem implementação
// Na classe Heroi (DEVE implementar)
public override void UsarPoder()
{
Console.WriteLine($"{Nome} usa poder para proteger!");
}
// Na classe Vilao (DEVE implementar, diferente de Heroi)
public override void UsarPoder()
{
Console.WriteLine($"{Nome} usa poder para causar caos!");
}
// TÓPICO: Sobrecarga (Overload)
// Múltiplos métodos com mesmo nome, mas parâmetros diferentes
public class Heroi : Personagem
{
public string Equipe { get; set; }
// Construtor 1: Com equipe
public Heroi(string nome, int nivel, string equipe) : base(nome, nivel)
{
Equipe = equipe;
}
// Construtor 2: Sem equipe (sobrecarga)
public Heroi(string nome, int nivel) : base(nome, nivel)
{
Equipe = "Sem equipe";
}
// TÓPICO: Sobrecarga de Métodos
// Múltiplos métodos SalvarVida com parâmetros diferentes
public void SalvarVida()
{
VidasSalvas++;
Console.WriteLine($"{Nome} salvou uma vida!");
}
// Sobrecarga: Salvar múltiplas vidas
public void SalvarVida(int quantidade)
{
VidasSalvas += quantidade;
Console.WriteLine($"{Nome} salvou {quantidade} vidas de uma vez!");
}
// Sobrecarga: Salvar vida com descrição
public void SalvarVida(string descricao)
{
VidasSalvas++;
Console.WriteLine($"{Nome} salvou uma vida: {descricao}");
}
}
// TÓPICO: Uso de Sobrecarga
Heroi batman = new Heroi("Batman", 85, "Liga da Justiça");
batman.SalvarVida(); // Chama SalvarVida() sem parâmetros
batman.SalvarVida(5); // Chama SalvarVida(int)
batman.SalvarVida("Criança em perigo"); // Chama SalvarVida(string)
// TÓPICO: Polimorfismo em Ação Real
// Sistema de batalha que funciona com qualquer personagem
public class Batalha
{
// TÓPICO: Método que Aceita Classe Base
// Funciona com Heroi, Vilao, ou qualquer classe derivada de Personagem
public static void IniciarBatalha(Personagem atacante, Personagem defensor)
{
Console.WriteLine($"=== BATALHA ===");
Console.WriteLine($"{atacante.Nome} vs {defensor.Nome}");
Console.WriteLine();
// TÓPICO: Polimorfismo
// Cada personagem usa poder de forma diferente
Console.WriteLine($"{atacante.Nome} ataca:");
atacante.UsarPoder(); // Polimorfismo!
Console.WriteLine($"{defensor.Nome} se defende:");
defensor.UsarPoder(); // Polimorfismo!
Console.WriteLine();
}
}
// TÓPICO: Usando Polimorfismo
// Criando personagens diferentes
Heroi batman = new Heroi("Batman", 85, "Liga da Justiça");
Vilao coringa = new Vilao("Coringa", 80, "Legião do Mal");
Heroi superman = new Heroi("Superman", 100, "Liga da Justiça");
// TÓPICO: Passando Objetos Diferentes para Mesmo Método
// O método aceita qualquer Personagem (herói ou vilão)
Batalha.IniciarBatalha(batman, coringa); // Herói vs Vilão
Batalha.IniciarBatalha(superman, coringa); // Herói vs Vilão
Batalha.IniciarBatalha(coringa, batman); // Vilão vs Herói (invertido)
// TÓPICO: Verificar Tipo em Tempo de Execução
// Às vezes precisamos saber o tipo real do objeto
foreach (Personagem personagem in personagens)
{
// TÓPICO: Operador 'is'
// Verifica se o objeto é de um tipo específico
if (personagem is Heroi)
{
// TÓPICO: Cast (Conversão de Tipo)
// Converte Personagem para Heroi para acessar métodos específicos
Heroi heroi = (Heroi)personagem;
heroi.SalvarVida(); // Método só de heróis
}
else if (personagem is Vilao)
{
Vilao vilao = (Vilao)personagem;
vilao.ExecutarPlano(); // Método só de vilões
}
}
// TÓPICO: Operador 'as' (Cast Seguro)
// Tenta converter, retorna null se não conseguir (não lança exceção)
Heroi heroi2 = personagem as Heroi;
if (heroi2 != null)
{
heroi2.SalvarVida();
}
is: Verificar tipo do objetoas: Cast seguro (retorna null se falhar)(Tipo): Cast explícito (lança exceção se falhar)Na próxima aula, veremos Try-Catch** e tratamento de exceções.