Virtual ve Override Anahtar Kelimeleri
Coddy'nin C# Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 21 / 70.
Türetilmiş bir sınıf bir metodu miras aldığında, bazen o metodun nasıl davranacağını tamamen değiştirmek istersiniz. virtual ve override anahtar kelimeleri, bunu kontrollü bir şekilde mümkün kılmak için birlikte çalışır.
Türetilmiş sınıfların bir metodun uygulamasını değiştirmesine izin verildiğini belirtmek için temel sınıfta o metodu virtual olarak işaretleyin:
public class Animal
{
public virtual void Speak()
{
Console.WriteLine("Some sound");
}
}
public class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("Woof!");
}
}Türetilmiş sınıftaki override anahtar kelimesi, derleyiciye temel metodu kasıtlı olarak geçersiz kıldığınızı söyler. Temel metotta virtual olmadan override kullanamazsınız.
Asıl güç, türetilmiş bir nesneyi tutmak için bir temel sınıf referansı kullandığınızda ortaya çıkar:
Animal myPet = new Dog();
myPet.Speak(); // Çıktı: Woof!myPet, Animal olarak bildirilmiş olsa bile, C# Speak() metodunun Dog versiyonunu çağırır. Buna çalışma zamanı çok biçimliliği (runtime polymorphism) denir; çağrılan asıl metot, değişkenin bildirilen türüne değil, nesnenin gerçek türüne bağlıdır.
Davranışı tamamen değiştirmek yerine genişletmek istiyorsanız, override işleminiz içinde base.Speak() kullanarak temel uygulamaya hala erişebilirsiniz.
Görev
KolayTüretilmiş sınıfların virtual ve override anahtar kelimelerini kullanarak temel sınıf davranışını nasıl tamamen geçersiz kılabileceğini gösteren ve aynı zamanda çalışma zamanı polimorfizminin (runtime polymorphism) gücünü sergileyen bir bildirim sistemi oluşturalım.
Kodunuzu düzenlemek için üç dosya oluşturacaksınız:
Notification.cs:Alertsad alanında (namespace) birNotificationsınıfı tanımlayın. Bu temel sınıf, birMessageözelliğine (string) ve bunu ayarlayan bir yapıcıya (constructor) sahip genel bir bildirimi temsil eder."Sending notification: {Message}"değerini döndürenSend()adında birvirtualmetot ekleyin.EmailNotification.cs:Alertsad alanındaNotificationsınıfından miras alan birEmailNotificationsınıfı tanımlayın. BirRecipientözelliği (string) ve hem mesajı hem de alıcıyı kabul eden bir yapıcı ekleyin (mesajı iletmek içinbasekullanın).Send()metodunu"Emailing {Recipient}: {Message}"döndürecek şekilde geçersiz kılın (override).SmsNotification.cs:Alertsad alanında yineNotificationsınıfından miras alan birSmsNotificationsınıfı tanımlayın. BirPhoneNumberözelliği (string) ve hem mesajı hem de telefon numarasını kabul eden bir yapıcı ekleyin.Send()metodunu"SMS to {PhoneNumber}: {Message}"döndürecek şekilde geçersiz kılın (override).Program.cs: Ana dosyanızda, giriş değerlerini kullanarak her üç bildirim türünden örnekler oluşturun. Ardından, her üçünü deNotificationdeğişkenlerinde saklayarak ve her biri üzerindeSend()metodunu çağırarak çalışma zamanı polimorfizmini gösterin.
Dört giriş alacaksınız:
- Bildirim mesajı
- E-posta alıcı adresi
- SMS için telefon numarası
Temel sınıf referansları olarak saklanan her bir bildirim üzerinde Send() çağrısının sonucunu yazdırın:
{base notification Send() result}
{email notification Send() result}
{sms notification Send() result}Örneğin, girişler Meeting at 3pm, alice@email.com ve 555-1234 ise çıktı şu şekilde olmalıdır:
Sending notification: Meeting at 3pm
Emailing alice@email.com: Meeting at 3pm
SMS to 555-1234: Meeting at 3pmHer üçü de Notification değişkenleri olarak saklanmasına rağmen, her birinin Send() metodunun kendi geçersiz kılınmış (overridden) sürümünü nasıl çağırdığına dikkat edin. İşte bu, iş başındaki çalışma zamanı polimorfizmidir!
Kopya kağıdı
Türetilmiş sınıfların geçersiz kılabileceği bir yöntemi işaretlemek için temel sınıfta virtual anahtar kelimesini kullanın:
public class Animal
{
public virtual void Speak()
{
Console.WriteLine("Some sound");
}
}Temel sınıf yöntem uygulamasını değiştirmek için türetilmiş bir sınıfta override anahtar kelimesini kullanın:
public class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("Woof!");
}
}Çalışma zamanı polimorfizmi (Runtime polymorphism), bir temel sınıf referansı türetilmiş bir nesneyi tuttuğunda gerçekleşir; çağrılan asıl yöntem, değişkenin bildirilen türüne değil, nesnenin gerçek türüne bağlıdır:
Animal myPet = new Dog();
myPet.Speak(); // Output: Woof!base kullanarak bir geçersiz kılma (override) içinden temel uygulamaya erişebilirsiniz:
public override void Speak()
{
base.Speak(); // Temel sınıf sürümünü çağırır
Console.WriteLine("Woof!");
}Kendin dene
using System;
using Alerts;
class Program
{
public static void Main(string[] args)
{
// Girdileri oku
string message = Console.ReadLine();
string email = Console.ReadLine();
string phone = Console.ReadLine();
// TODO: Üç bildirim türünün de örneklerini oluşturun
// Polimorfizmi (çok biçimlilik) göstermek için bunları Notification değişkenlerinde saklayın
// TODO: Temel bir Notification oluşturun
Notification baseNotification;
// TODO: Bir EmailNotification oluşturun (Notification türünde saklanan)
Notification emailNotification;
// TODO: Bir SmsNotification oluşturun (Notification türünde saklanan)
Notification smsNotification;
// TODO: Her biri üzerinde Send() metodunu çağırın ve sonuçları yazdırın
// Çalışma zamanı polimorfizmi nedeniyle geçersiz kılınan (overridden) metotlar çağrılacaktır
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici Dosyalarİsim Alanları ve YönergelerSınıf ve Nesnelere Giriş'this' Anahtar KelimesiMetotlar ve ParametrelerAlanlar ve ÖzelliklerYapıcı MetotlarNesne BaşlatıcılarÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (:) Sözdizimi'base' Anahtar KelimesiVirtual ve Override Anahtar KelimeleriSealed Sınıflar'object' Temel SınıfıÖzet - Çalışan Hiyerarşisi7İleri Düzey Özellikler
Operatör Aşırı Yüklemeİndeksleyiciler (this[])ToString() Geçersiz KılmaGenişletme MetotlarıÖzet - Özel Liste10Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişThread-Safe SingletonFactory KalıbıObserver Kalıbı (Olaylar)Strategy Kalıbı2Özellikler ve Statik Üyeler
Otomatik Uygulanan ÖzelliklerSadece Okunur/Yazılır ÖzelliklerStatik Alanlar ve MetotlarStatik Sınıflarİfade Gövdeli Üyeler5Polimorfizm ve Arayüzler
Derleme vs Çalışma Zamanı PolimorfizmiArayüz vs Soyut SınıfÇoklu ArayüzlerBelirgin ArayüzlerUpcasting ve DowncastingÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kalıtım yerine KompozisyonGenerics (Sınıflar ve Metotlar)Delegates ve EventlerAttributes ve ReflectionIDisposable ve using İfadesiDependency Injection Temelleri11Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit Kalıbı3Sınıf Mimarisi
Örnek vs Statik Veri'readonly' ve 'const' Anahtar KelimeleriDestekleyici Alanlar (Backing Fields)Özet - Banka Hesabı Yöneticisi6Kapsülleme
Erişim BelirleyicilerKapsülleme için ÖzelliklerVeri Gizleme UygulamasıDeğişmezlik KalıplarıÖzet - Öğrenci Kayıtları