Menu
Coddy logo textTech

Słowa kluczowe virtual i override

Część sekcji Programowanie obiektowe ścieżki C# w Coddy. Lekcja 21 z 70.

Gdy klasa pochodna dziedziczy metodę, czasami chcesz całkowicie zmienić jej działanie. Słowa kluczowe virtual i override współdziałają, aby umożliwić to w kontrolowany sposób.

Oznacz metodę jako virtual w klasie bazowej, aby zasygnalizować, że klasy pochodne mogą zastąpić jej implementację:

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

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

Słowo kluczowe override w klasie pochodnej informuje kompilator, że celowo zastępujesz metodę klasy bazowej. Jeśli metoda klasy bazowej nie ma słowa kluczowego virtual, nie możesz użyć override.

Prawdziwa moc ujawnia się, gdy używasz referencji do klasy bazowej, aby przechowywać obiekt klasy pochodnej:

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

Mimo że myPet jest zadeklarowana jako Animal, C# wywołuje wersję Dog metody Speak(). Nazywa się to polimorfizmem czasu wykonania — wywoływana metoda zależy od rzeczywistego typu obiektu, a nie od zadeklarowanego typu zmiennej.

Nadal możesz uzyskać dostęp do implementacji bazowej za pomocą base.Speak() wewnątrz nadpisanej metody, jeśli chcesz rozszerzyć zachowanie, zamiast całkowicie je zastępować.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system powiadomień, który pokazuje, jak klasy pochodne mogą całkowicie zastępować zachowanie klasy bazowej za pomocą słów kluczowych virtual i override, a także demonstruje możliwości polimorfizmu w czasie działania.

Utworzysz trzy pliki, aby uporządkować swój kod:

  • Notification.cs: Zdefiniuj klasę Notification w przestrzeni nazw Alerts. Ta klasa bazowa reprezentuje ogólne powiadomienie za pomocą właściwości Message (string) i konstruktora, który ją ustawia. Dodaj metodę virtual o nazwie Send(), która zwraca "Sending notification: {Message}".
  • EmailNotification.cs: Zdefiniuj klasę EmailNotification w przestrzeni nazw Alerts, która dziedziczy po klasie Notification. Dodaj właściwość Recipient (string) i konstruktor, który przyjmuje zarówno wiadomość, jak i odbiorcę (użyj base, aby przekazać wiadomość). Zastąp metodę Send(), aby zwracała "Emailing {Recipient}: {Message}".
  • SmsNotification.cs: Zdefiniuj klasę SmsNotification w przestrzeni nazw Alerts, która również dziedziczy po klasie Notification. Dodaj właściwość PhoneNumber (string) i konstruktor, który przyjmuje zarówno wiadomość, jak i numer telefonu. Zastąp metodę Send(), aby zwracała "SMS to {PhoneNumber}: {Message}".
  • Program.cs: W pliku głównym utwórz obiekty wszystkich trzech typów powiadomień, używając wartości wejściowych. Następnie zademonstruj polimorfizm w czasie działania, przechowując wszystkie trzy w zmiennych typu Notification i wywołując Send() dla każdej z nich.

Otrzymasz cztery dane wejściowe:

  • Wiadomość powiadomienia
  • Adres e-mail odbiorcy
  • Numer telefonu do SMS

Wypisz wynik wywołania Send() dla każdego powiadomienia przechowywanego jako odwołanie do klasy bazowej:

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

Na przykład, jeśli dane wejściowe to Meeting at 3pm, alice@email.com i 555-1234, wynik powinien wyglądać tak:

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

Zauważ, że mimo iż wszystkie trzy obiekty są przechowywane w zmiennych typu Notification, każdy wywołuje własną, zastąpioną wersję metody Send(). Oto polimorfizm w czasie działania!

Spróbuj swoich sił

using System;
using Alerts;

class Program
{
    public static void Main(string[] args)
    {
        // Odczytaj dane wejściowe
        string message = Console.ReadLine();
        string email = Console.ReadLine();
        string phone = Console.ReadLine();

        // TODO: Utwórz instancje wszystkich trzech typów powiadomień
        // Przechowaj je w zmiennych typu Notification, aby zademonstrować polimorfizm
        
        // TODO: Utwórz obiekt bazowej klasy Notification
        Notification baseNotification;
        
        // TODO: Utwórz obiekt EmailNotification (przechowywany w zmiennej typu Notification)
        Notification emailNotification;
        
        // TODO: Utwórz obiekt SmsNotification (przechowywany w zmiennej typu Notification)
        Notification smsNotification;
        
        // TODO: Wywołaj Send() dla każdego obiektu i wypisz wyniki
        // Dzięki polimorfizmowi w czasie wykonywania zostaną wywołane metody przesłonięte
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C# online