31 Ekim 2011 Pazartesi

C# Member Hiding

Nesne yönelimli programlamanın temel felsefelerinden birisi kalıtımdır( inheritance). Kalıtım yolu ile taban sınıfın public veya protected olan üyelerine sahip olabilmek söz konusu idi. Ancak bazı üyeleri aynı isim altında tekrar tanımladığımız durumlar olabilmektedir.  Bu durumda compiler’ın nasıl davranacağını incelemeye çalışacağız.

Urun adında taban sınıfımız olsun. Daha sonra da Kitap adında bir sınıf tasarlayalım ve Urun sınıfından kalıtalım.

class Urun

    {

        public int Id { get; set; }

        public string Ad { get; set; }

 

        public void Test()

        {

            Console.WriteLine("Ben Urun sınıfının üyesiyim.");

        }

    }

 

class Kitap : Urun

    {

        public string Yazar { get; set; }    

    }

Kitap tipinden bir nesne örneklediğimiz zaman, Test adlı public metoda erişim yapılabilir. Urun sınıfından kalıtım yapılarak, Test adındaki üye, Kitap tipinden nesneler için erişilebilir hale gelmiştir.

class Program

    {

        static void Main(string[] args)

        {

            Kitap kitap = new Kitap();

            kitap.Test();

        }

    }

Programı çalıştıralım.

image

Test adlı üyeyi, Kitap sınıfı içerisinde de tanımlayalım.

class Kitap : Urun

    {

        public string Yazar { get; set; }

 

        public void Test()

        {

            Console.WriteLine("Ben Kitap sınıfının üyesiyim.");

        }

    }

Yine Kitap tipinden bir nesne örnekleyerek Test metodunu çağıralım.

class Program

    {

        static void Main(string[] args)

        {

            Kitap kitap = new Kitap();

            kitap.Test();

        }

    }

Programı çalıştıralım.

image

Gördüğünüz gibi, taban sınıftaki metot yok sayılmış ve Kitap sınıfındaki metot çalışmıştır. Ancak programı çalıştırırken derleyici aşağıdaki gibi bir uyarı verir.

'MemberHiding.Kitap.Test()' hides inherited member 'MemberHiding.Urun.Test()'. Use the new keyword if hiding was intended.

Kitap sınıfındaki Test adlı üyenin, Urun sınıfında saklı olduğu ve new anahtar sözcüğünün kullanılması gerektiği belirtilmiştir. “new” anahtar sözcüğünü kullanarak compiler’a, Urun sınıfındaki aynı isimli üyeyi görmezden gelmesini söylüyoruz.  Kodumuzu aşağıdaki hale getirip çalıştıralım.

class Kitap : Urun

    {

        public string Yazar { get; set; }

 

        //new public void Test() şeklinde de yazabiliriz.

        public new void Test()

        {

            Console.WriteLine("Ben Kitap sınıfının üyesiyim.");

        }

    }

Kitap tipinden bir nesne örneklediğimizde, aynı sonucu alacağız.

class Program

    {

        static void Main(string[] args)

        {

            Kitap kitap = new Kitap();

            kitap.Test();

        }

    }

image

Kitap sınıfından kalıtılan başka bir sınıf içerisinde de Test adlı üyeyi tanımlayalım.

class A : Kitap

    {

        public new void Test()

        {

            Console.WriteLine("A sınıfındaki metot çalıştı");

        }

    }

A tipinde bir nesne örnekleyerek Test metodunu çağıralım.

class Program

    {

        static void Main(string[] args)

        {

            A a = new A();

            a.Test();

        }

    }

Programı çalıştırdığımızda A sınıfındaki metodun çalıştığını göreceğiz.

image

 

Şimdi de olaya başka bir açıdan yaklaşalım. Kitap, bir Urun olduğundan dolayı, Kitap tipinden bir nesne, Urun tipinden bir değişken ile işaret edilebilir. Bu durumda hangi üyenin çalışacağını test etmeye çalışalım.

class Program

    {

        static void Main(string[] args)

        {

            Urun urun = new Kitap();

            urun.Test();

        }

    }

Programı çalıştıralım.

image

NOT : Member hiding yaptığımız zaman, işaretçinin tipine bakılır. İşaretçi hangi tipte ise, o tip içerisinde tanımlanmış olan üye çalışır. Ancak virtual üyelerde durum tam tersidir. override edilen bir üye için öncelikle eşitliğin sağ tarafı, yani nesnenin tipi önemlidir. Eğer Test adlı metot virtual olsaydı ve Kitap sınıfında override edilseydi, Yukarıdaki kodu çalıştırdığımızda, Kitap sınıfındaki metot çalışacaktı. İşaret edilen nesne Kitap tipinden olduğu için, override edilen metot çalışacaktı.



0 yorum:

Yorum Gönder