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ółpracują ze sobą, 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. Bez virtual w metodzie klasy bazowej nie możesz użyć override.
Prawdziwa moc ujawnia się, gdy używasz referencji do klasy bazowej, aby przechować 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 w czasie wykonywania — wywoływana metoda zależy od rzeczywistego typu obiektu, a nie od zadeklarowanego typu zmiennej.
Nadal możesz uzyskać dostęp do implementacji klasy bazowej za pomocą base.Speak() wewnątrz przesłoniętej metody, jeśli chcesz rozszerzyć jej działanie, zamiast całkowicie je zastępować.
Wyzwanie
ŁatwyZbudujmy system powiadomień, który pokazuje, jak klasy pochodne mogą całkowicie zastąpić zachowanie klasy bazowej za pomocą słów kluczowych virtual i override, a także demonstruje możliwości polimorfizmu w czasie wykonywania.
Utworzysz trzy pliki, aby uporządkować swój kod:
Notification.cs: Zdefiniuj klasęNotificationw przestrzeni nazwAlerts. Ta klasa bazowa reprezentuje ogólne powiadomienie z właściwościąMessage(typu string) i konstruktorem, który ją ustawia. Dodaj metodęvirtualo nazwieSend(), która zwraca"Sending notification: {Message}".EmailNotification.cs: Zdefiniuj klasęEmailNotificationw przestrzeni nazwAlerts, która dziedziczy poNotification. Dodaj właściwośćRecipient(typu string) i konstruktor, który przyjmuje zarówno wiadomość, jak i odbiorcę (użyjbase, aby przekazać wiadomość). Nadpisz metodęSend(), aby zwracała"Emailing {Recipient}: {Message}".SmsNotification.cs: Zdefiniuj klasęSmsNotificationw przestrzeni nazwAlerts, która również dziedziczy poNotification. Dodaj właściwośćPhoneNumber(typu string) i konstruktor, który przyjmuje zarówno wiadomość, jak i numer telefonu. Nadpisz metodęSend(), aby zwracała"SMS to {PhoneNumber}: {Message}".Program.cs: W pliku głównym utwórz instancje wszystkich trzech typów powiadomień, używając wartości wejściowych. Następnie zademonstruj polimorfizm w czasie wykonywania, przechowując wszystkie trzy w zmiennych typuNotificationi wywołując dla każdej z nichSend().
Otrzymasz cztery dane wejściowe:
- Treść powiadomienia
- Adres e-mail odbiorcy
- Numer telefonu do SMS-a
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 danymi wejściowymi są Meeting at 3pm, alice@email.com i 555-1234, dane wyjściowe powinny wyglądać następująco:
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ą nadpisaną wersję Send(). Oto polimorfizm w czasie wykonywania w praktyce!
Spróbuj swoich sił
using System;
using Alerts;
class Program
{
public static void Main(string[] args)
{
// Wczytaj dane wejściowe
string message = Console.ReadLine();
string email = Console.ReadLine();
string phone = Console.ReadLine();
// TODO: Utwórz instancje wszystkich trzech typów powiadomień
// Przechowuj je w zmiennych typu Notification, aby zademonstrować polimorfizm
// TODO: Utwórz bazową instancję Notification
Notification baseNotification;
// TODO: Utwórz instancję EmailNotification (przechowywaną jako typ Notification)
Notification emailNotification;
// TODO: Utwórz instancję SmsNotification (przechowywaną jako typ Notification)
Notification smsNotification;
// TODO: Wywołaj Send() na każdej z nich i wypisz wyniki
// Metody przesłaniające zostaną wywołane dzięki polimorfizmowi w czasie wykonania
}
}
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