Menu
CoddyTech

Palabras clave Virtual y Override

Parte de la sección Programación Orientada a Objetos del Journey de C# de Coddy. Lección 21 de 70.

Cuando una clase derivada hereda un método, a veces quieres cambiar por completo cómo se comporta ese método. Las palabras clave virtual y override trabajan juntas para hacerlo posible de forma controlada.

Marca un método como virtual en la clase base para indicar que las clases derivadas pueden reemplazar su implementación:

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

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

La palabra clave override en la clase derivada le indica al compilador que estás reemplazando intencionalmente el método de la clase base. Sin virtual en el método de la clase base, no puedes usar override.

El verdadero potencial se muestra cuando usas una referencia a la clase base para contener un objeto derivado:

Animal myPet = new Dog();
myPet.Speak();  // Salida: Woof!

Aunque myPet se declara como Animal, C# llama a la versión de Dog de Speak(). Esto se llama polimorfismo en tiempo de ejecución: el método que se llama realmente depende del tipo real del objeto, no del tipo declarado de la variable.

Aún puedes acceder a la implementación base usando base.Speak() dentro de tu sobrescritura si quieres ampliar el comportamiento en lugar de reemplazarlo por completo.

challenge icon

Desafío

Fácil

Vamos a crear un sistema de notificaciones que demuestra cómo las clases derivadas pueden sobrescribir por completo el comportamiento de la clase base mediante las palabras clave virtual y override, y también muestra el poder del polimorfismo en tiempo de ejecución.

Crearás tres archivos para organizar tu código:

  • Notification.cs: Define una clase Notification en el espacio de nombres Alerts. Esta clase base representa una notificación genérica con una propiedad Message (cadena) y un constructor que le asigna un valor. Incluye un método virtual llamado Send() que devuelve "Sending notification: {Message}".
  • EmailNotification.cs: Define una clase EmailNotification en el espacio de nombres Alerts que hereda de Notification. Añade una propiedad Recipient (cadena) y un constructor que acepte tanto el mensaje como el destinatario (usa base para pasar el mensaje). Sobrescribe el método Send() para que devuelva "Emailing {Recipient}: {Message}".
  • SmsNotification.cs: Define una clase SmsNotification en el espacio de nombres Alerts que también hereda de Notification. Añade una propiedad PhoneNumber (cadena) y un constructor que acepte tanto el mensaje como el número de teléfono. Sobrescribe Send() para que devuelva "SMS to {PhoneNumber}: {Message}".
  • Program.cs: En tu archivo principal, crea instancias de los tres tipos de notificación usando los valores de entrada. Después, demuestra el polimorfismo en tiempo de ejecución almacenando las tres en variables de tipo Notification y llamando a Send() en cada una.

Recibirás cuatro entradas:

  • El mensaje de la notificación
  • La dirección de correo electrónico del destinatario
  • El número de teléfono para SMS

Imprime el resultado de llamar a Send() en cada notificación, almacenada como una referencia a la clase base:

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

Por ejemplo, si las entradas son Meeting at 3pm, alice@email.com y 555-1234, el resultado debería ser:

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

Fíjate en que, aunque las tres están almacenadas en variables de tipo Notification, cada una llama a su propia versión sobrescrita de Send(). ¡Eso es el polimorfismo en tiempo de ejecución en acción!

Pruébalo tú mismo

using System;
using Alerts;

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

        // TODO: Crea instancias de los tres tipos de notificación
        // Guárdalas en variables de tipo Notification para demostrar el polimorfismo
        
        // TODO: Crea una Notification base
        Notification baseNotification;
        
        // TODO: Crea una EmailNotification (almacenada como tipo Notification)
        Notification emailNotification;
        
        // TODO: Crea una SmsNotification (almacenada como tipo Notification)
        Notification smsNotification;
        
        // TODO: Llama a Send() en cada una e imprime los resultados
        // Los métodos sobrescritos se invocarán debido al polimorfismo en tiempo de ejecución
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de C# online