Menu
CoddyTech

Palavras-chave Virtual e Override

Parte da seção Programação Orientada a Objetos do Journey de C# da Coddy. Lição 21 de 70.

Quando uma classe derivada herda um método, às vezes você quer mudar completamente o comportamento desse método. As palavras-chave virtual e override trabalham juntas para tornar isso possível de forma controlada.

Marque um método como virtual na classe base para indicar que as classes derivadas podem substituir sua implementação:

public class Animal
{
    public virtual void Speak()
    {
        Console.WriteLine("Some sound");
    }
}

public class Dog : Animal
{
    public override void Speak()
    {
        Console.WriteLine("Woof!");
    }
}

A palavra-chave override na classe derivada informa ao compilador que você está substituindo intencionalmente o método da classe base. Sem virtual no método da classe base, você não pode usar override.

O verdadeiro poder aparece quando você usa uma referência da classe base para armazenar um objeto derivado:

Animal myPet = new Dog();
myPet.Speak();  // Saída: Woof!

Embora myPet seja declarado como Animal, C# chama a versão de Dog de Speak(). Isso é chamado de polimorfismo em tempo de execução - o método efetivamente chamado depende do tipo real do objeto, não do tipo declarado da variável.

Você ainda pode acessar a implementação base usando base.Speak() dentro da sua sobrescrita se quiser estender o comportamento em vez de substituí-lo completamente.

challenge icon

Desafio

Fácil

Vamos criar um sistema de notificações que demonstra como classes derivadas podem substituir completamente o comportamento da classe base usando as palavras-chave virtual e override, além de mostrar o poder do polimorfismo em tempo de execução.

Você criará três arquivos para organizar seu código:

  • Notification.cs: Defina uma classe Notification no namespace Alerts. Essa classe base representa uma notificação genérica com uma propriedade Message (string) e um construtor que a define. Inclua um método virtual chamado Send() que retorna "Sending notification: {Message}".
  • EmailNotification.cs: Defina uma classe EmailNotification no namespace Alerts que herda de Notification. Adicione uma propriedade Recipient (string) e um construtor que aceite tanto a mensagem quanto o destinatário (use base para passar a mensagem). Substitua o método Send() para retornar "Emailing {Recipient}: {Message}".
  • SmsNotification.cs: Defina uma classe SmsNotification no namespace Alerts que também herda de Notification. Adicione uma propriedade PhoneNumber (string) e um construtor que aceite tanto a mensagem quanto o número de telefone. Substitua Send() para retornar "SMS to {PhoneNumber}: {Message}".
  • Program.cs: No arquivo principal, crie instâncias dos três tipos de notificação usando os valores de entrada. Em seguida, demonstre o polimorfismo em tempo de execução armazenando as três em variáveis Notification e chamando Send() em cada uma.

Você receberá quatro entradas:

  • A mensagem da notificação
  • O endereço de e-mail do destinatário
  • O número de telefone para SMS

Imprima o resultado da chamada de Send() em cada notificação, armazenada como referência da classe base:

{base notification Send() result}
{email notification Send() result}
{sms notification Send() result}

Por exemplo, se as entradas forem Meeting at 3pm, alice@email.com e 555-1234, a saída deverá ser:

Sending notification: Meeting at 3pm
Emailing alice@email.com: Meeting at 3pm
SMS to 555-1234: Meeting at 3pm

Observe que, embora as três estejam armazenadas em variáveis Notification, cada uma chama sua própria versão substituída de Send(). Isso é o polimorfismo em tempo de execução em ação!

Experimente você mesmo

using System;
using Alerts;

class Program
{
    public static void Main(string[] args)
    {
        // Leia as entradas
        string message = Console.ReadLine();
        string email = Console.ReadLine();
        string phone = Console.ReadLine();

        // TODO: Crie instâncias dos três tipos de notificação
        // Armazene-as em variáveis do tipo Notification para demonstrar o polimorfismo
        
        // TODO: Crie uma Notification base
        Notification baseNotification;
        
        // TODO: Crie uma EmailNotification (armazenada como tipo Notification)
        Notification emailNotification;
        
        // TODO: Crie uma SmsNotification (armazenada como tipo Notification)
        Notification smsNotification;
        
        // TODO: Chame Send() em cada uma e imprima os resultados
        // Os métodos sobrescritos serão chamados devido ao polimorfismo em tempo de execução
    }
}
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 C# online