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ć.
Wyzwanie
ŁatwyZbudujmy 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ęNotificationw przestrzeni nazwAlerts. Ta klasa bazowa reprezentuje ogólne powiadomienie za pomocą właściwościMessage(string) i konstruktora, który ją ustawia. Dodaj metodęvirtualo nazwieSend(), która zwraca"Sending notification: {Message}".EmailNotification.cs: Zdefiniuj klasęEmailNotificationw przestrzeni nazwAlerts, która dziedziczy po klasieNotification. Dodaj właściwośćRecipient(string) i konstruktor, który przyjmuje zarówno wiadomość, jak i odbiorcę (użyjbase, aby przekazać wiadomość). Zastąp metodęSend(), aby zwracała"Emailing {Recipient}: {Message}".SmsNotification.cs: Zdefiniuj klasęSmsNotificationw przestrzeni nazwAlerts, która również dziedziczy po klasieNotification. 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 typuNotificationi wywołującSend()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 3pmZauważ, ż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
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrznePrzestrzenie nazw i dyrektywyWprowadzenie do klas i obiektówSłowo kluczowe „this”Metody i parametryPola a właściwościKonstruktoryInicjalizatory obiektówPodsumowanie — prosty kalkulator4Dziedziczenie
Podstawowa składnia dziedziczenia (:)Słowo kluczowe 'base'Słowa kluczowe virtual i overrideKlasy sealedBazowa klasa 'object'Powtórzenie – hierarchia pracowników7Zaawansowane funkcje
Przeciążanie operatorówIndeksery (this[])Nadpisywanie ToString()Metody rozszerzającePodsumowanie – własna lista2Właściwości i składowe statyczne
Właściwości automatyczneWłaściwości tylko do odczytu i zapisuPola i metody statyczneKlasy statyczneSkładowe z ciałem wyrażeniowym5Polimorfizm i interfejsy
Polimorfizm czasu kompilacji a czasu wykonaniaInterfejs a klasa abstrakcyjnaWiele interfejsówJawne implementowanie interfejsówRzutowanie w górę i w dółPowtórka — kalkulator kształtów8Zaawansowane koncepcje OOP
Kompozycja zamiast dziedziczeniaTypy generyczne (klasy i metody)Delegaty i zdarzeniaAtrybuty i refleksjaIDisposable i instrukcja usingPodstawy wstrzykiwania zależności11Wzorce projektowe, część 2
Wzorzec poleceniaWzorzec adapteraWzorzec dekoratoraWzorzec metody szablonowejWzorzec stanuWzorzec kompozytu3Architektura klas
Dane instancji a dane statyczneSłowa kluczowe 'readonly' i 'const'Pola zapasowePowtórzenie — menedżer kont bankowych6Hermetyzacja
Modyfikatory dostępuWłaściwości w hermetyzacjiImplementacja ukrywania danychWzorce niezmiennościPowtórka — dane studentów9Argumenty zmiennej liczby
Słowo kluczowe „params”Parametry opcjonalneArgumenty nazwanePrzeciążanie metodPoćwicz samodzielnie: Kompilator C# online