Virtual(Sanal) Metotlar
İçindekiler
Bugünkü makalemizde sanal metotların kalıtım içerisindeki rolüne bakacağız. Sanal metotlar, temel sınıflarda tanımlanan ve türeyen sınıflarda geçersiz kılınabilen metotlardır. Bu tanım bize pek bir şey ifade etmez aslında. O halde gelin sanal metodların neden kullanırız, once buna bakalım. Bu amaçla minik bir örnek ile işe başlıyoruz.
using System;
namespace ConsoleApplication1
{
public class Temel
{
public Temel()
{
}
public void Yazdir()
{
Console.WriteLine("Ben TEMEL(BASE) sinifim");
}
}
public class Tureyen : Temel
{
public Tureyen()
{
}
public void Yazdir()
{
Console.WriteLine("Ben TUREYEN(DERIVED) sinifim");
}
}
class Class1
{
static void Main(string[] args)
{
Temel bs;
Tureyen drv =new Tureyen();
bs = drv;
bs.Yazdir();
}
}
}
Bu örneği çalıştırmadan once satırlarımızı bir inceleyelim. Kodumuz Temel isimli bir base class ve Tureyen isimli bir Derived Class vardır. Her iki sınıf içinde Yazdir isimli iki metod tanımlanmıştır. Main metodu içinde Temel sınıftan türettiğimiz bir nesneye (bs nesnesi) Tureyen sınıf tipinden bir nesneyi (drv nesnesi) aktarıyoruz. Ardından bs nesnemizin Yazdir isimli metodunu çağırıyoruz. Sizce derleyici hangi sınıfın yazdır metodunu çağıracaktır.
Drv nesnemiz Tureyen sınıf nesnesi olduğundan ve Temel sınıftan kalıtımsal olarak türetildiğinden bs isimli nesnemize aktarılabilmiştir. Şu durumda bs isimli Temel sınıf nesnemiz drv isimli Tureyen sınıf nesnemizi taşımaktadır. Bu tip bir atama, base-derived ilişkide sınıflar için geçerli bir atamadır. Sorun bs isimli nesne için Yazdir metodunun çağrılmasındadır. Biz burada Tureyen sınıf nesnesini aktardığımız için bu sınıfa ait Yazdir metodunun çalıştırılmasını bekleriz. Oysaki sonuç aşağıdaki gibi olacaktır.

Şekil 1. Temel Sınıfın Yazdir metodu çağırıldı.
Görüldüğü gibi Temel sınıfa ait Yazdir metodu çalıştırılmıştır. Bir çözüm olarak daha önceki kalıtım kavramını anlattığımız makalemizde incelediğimiz new anahtar kelimesini Tureyen isimli derived class içinde kullanmayı düşünebilirsiniz. Bir de böyle deneyelim, bakalım neler olacak.
using System;
namespace ConsoleApplication1
{
public class Temel
{
public Temel()
{
}
public void Yazdir()
{
Console.WriteLine("Ben TEMEL(BASE) sinifim");
}
}
public class Tureyen : Temel
{
public Tureyen()
{
}
public new void Yazdir()
{
Console.WriteLine("Ben TUREYEN(DERIVED) sinifim");
}
}
class Class1
{
static void Main(string[] args)
{
Temel bs;
Tureyen drv =new Tureyen();
bs = drv;
bs.Yazdir();
}
}
}
Ancak new anahtar kelimesini kullanmış olsak da sonuç yine aynı olacaktır ve aşağıdaki görüntüyü alacağız.

Şekil 2. Yine style=’mso-spacerun:yes’> Temel Sınıfın Yazdir metodu çağırıldı.
İşte bu noktada çözüm, Temel sınıftaki metodumuzu Virtual (sanal) tanımlamak ve aynı metodu, Tureyen sınıf içerisinde Override (Geçersiz Kılmak) etmektir. Sanal metodların kullanım amacı budur; Base sınıfta yer alan metod yerine, base sınıfa aktarılan nesnenin üretildiği derived class’taki metodu çağırmaktır.
Şimdi örneğimizi buna göre değiştirelim.
using System;
namespace ConsoleApplication1
{
public class Temel
{
public Temel()
{
}
public virtual void Yazdir()
{
Console.WriteLine("Ben TEMEL(BASE) sinifim");
}
}
public class Tureyen : Temel
{
public Tureyen()
{
}
public override void Yazdir()
{
Console.WriteLine("Ben TUREYEN(DERIVED) sinifim");
}
}
class Class1
{
static void Main(string[] args)
{
Temel bs;
Tureyen drv =new Tureyen();
bs = drv;
bs.Yazdir();
}
}
}

Şekil 3. Tureyen sınıftaki Yazdir metodu çağırılmıştır.
Burada önemli olan nokta, Temel sınıfaki metodun virtual anahtar kelimesi ile tanımlanması, Tureyen sınıftaki metodun ise override anahtar kelimesi ile tanımlanmış olmasıdır. Sanal metodları kullanırken dikkat etmemiz gereken bir takım noktalar vardır. Bu noktalar;
- İki metodda aynı isime sahip olmalıdır.
- İki metodda aynı tür ve sayıda parametre almalıdır.
- İki metodunda geri dönüş değerleri aynı olmalıdır.
- Metodların erişim haklarını aynı olmalıdır. Biri public tanımlanmış ise diğeride public olmalıdır.
- Temel sınıftaki metodu türeyen sınıfta override (geçersiz) hale getimez isek metod geçersiz kılınamaz.
- Sadece virtual olarak tanımlanmış metodları override edebiliriz. Herhangi bir base class yöntemini türeyen sınıfta override edemeyiz.
Bu noktalara dikkat etmemiz gerekmektedir. Değerli Okurlarım, geldik bir makalemizin daha sonuna. Bir sonraki makalemizde görüşmek dileğiyle hepinize mutlu günler dilerim.