Bir sınıf başka bir sınıftan türetildiğinde tüm özelliklerini miras alır. Türemiş sınıf içinde türetilen sınıftan gelen bazı özellikleri değiştirmek isteyebiliriz (ve yapabiliriz de). Sınıfın miras aldığı özelliklerin değiştirilebilmesine -ve nesne üzerinden çağrılabilmesine- çok biçimlilik denir.

Bir sitedeki temsili üye ve admin sınıflarını oluşturalım. Üyeler çıkış butonuna tıkladığında normal çıkış yapsın. Admin çıkış yaptığında ne olur ne olmaz diyerek çıkıştan sonra tarayıcı çerezlerini de temizlesin.

class Uye
{
    public string Ad { get; set; }

    public virtual void CikisYap ()
    {
        Console.WriteLine(this.Ad + ": Çıkış yaptım.");
    }
}

class Admin : Uye
{
    public override void CikisYap()
    {
        base.CikisYap();

        Console.WriteLine(this.Ad + ": Çerezleri temizledim.");
    }
}

Overriding (Ezme)

Değiştirmemiz gereken metot CikisYap. Bu metodu virtual olarak tanımladık çünkü değiştireceğiz. Türemiş sınıfta (derived class) ise aynı methoda override ifadesini ekledik. Böylece yeni yazdığımız metot eskisinin yerini alacak. Bu yaptığımız işleme method overriding (metot ezme) denir.

Admin sınıfında önce standart çıkış işlemini yapmak için base referansı ile türetilen sınıftaki base class metodu çağırdık ve ardından yapmak istediğimiz ek işlemi yaptık. Aşağıdaki gibi yazdığımız kodu test edersek olayların tam da istediğimiz gibi gerçekleştiğini görürüz.

Uye uye = new Uye { Ad = "Umut" };
Admin admin = new Admin { Ad = "Çağdaş" };

uye.CikisYap();
admin.CikisYap();

Hiding (Gizleme)

Metotlara virtual ve override ifadelerini eklemeseydik de şuanki senaryoda durum değişmeyecekti. Ancak derived class içinde base class'a ait bir methodu override etmeden tekrar tanımlarsanız base class'taki hali hala muhafaza ediliyor olacaktır. Bu duruma method hiding (metot gizleme) denir. Şimdi farklı bir senaryo deneyelim.

class Uye
{
    public string Ad { get; set; }

    public void CikisYap ()
    {
        Console.WriteLine(this.Ad + ": Çıkış yaptım.");
    }
}

class Admin : Uye
{
    public void CikisYap()
    {
        base.CikisYap();

        Console.WriteLine(this.Ad + ": Çerezleri temizledim.");
    }
}

Bu sefer üyeyi Admin sınıfından referans alıyoruz.

Uye uye = new Admin { Ad = "Umut" };
uye.CikisYap();

Admin admin = new Admin { Ad = "Çağdaş" };
admin.CikisYap();

Üyeyi admin sınıfından referans aldığımız için çıkış yaparken çerezleri temizlemesini bekledik ama yapmadı. Çünkü method hiding kullandık. Metot gizlemede nesne hangi sınıfın referansından çağrılırsa oradaki metodu çalıştırır. Metot ezmede ise söz konusu metot en son ne zaman override edilmiş ise o halini çalıştırır. Kodun istediğimiz gibi çalışması için metotlara tekrar virtual ve override deyimlerini eklememiz gerekiyor.

Shadowing (Gölgeleme)

Gölgeleme işlemi new deyimi ile yapılır. Gölgelenen metodun bulunduğu sınıf base sınıfın referansına atanırsa ilgili metot çağrıldığında atanan değil referans alınan sınıftaki metot çalıştırılır. Admin sınıfındaki metodu aşağıdki gibi değiştirelim.

public new  void CikisYap()
{
    base.CikisYap();

    Console.WriteLine(this.Ad + ": Çerezleri temizledim.");
}

Ardından aşağıdaki gibi bir deneme yapalım.

Admin admin = new Admin { Ad = "Umut" };

Uye uye = (Admin)admin;
uye.CikisYap();

Nesnenin Admin sınıfındaki metodu görmezden gelip referans aldığı Uye sınıfındaki metodu çalıştırdığını göreceksiniz. Ezme işlemi yapmak için virtual deyimi şarttır fakat gölgeleme için değildir.