19 Kasım 2017 Pazar

C#'ta Kalıtım (Inheritance) - Kalıtımda Yapılandırıcılar ve Ad Gizleme - Part 3

Merhaba,

Bir önceki yazıda kalıtımda üye erişimi konusunu ele almıştık. Bu yazıda ise kalıtımda yapılandırıcılardan ve ardından ad gizleme kavramından bahsedeceğim.

Bildiğiniz üzere her sınıfın bir yapılandırıcısı vardır. Siz tanımlamasanız bile default bir yapılandırıcı vardır. Bir kalıtım hiyerarşisinde hem temel sınıf hem de türetilmiş sınıfların kendi yapılandırıcılarını çağırmaları mümkündür. Peki bu durumda türetilmiş sınıf hangi yapılandırıcıyı çağıracak gibi bir soru akla gelebilir ki gelmelidir. Cevap: her iki sınıf da kendi yapılandırısını çağırır. Bu akla yatkındır çünkü temel sınıf, türetilmiş sınıfın ne yaptığından habersizdir ve kendi işini kendisi görecektir.

Aşağıdaki örnek bunu ifade eder:

 class A
    {
        public A() {
            Console.WriteLine("Bu temel sınıfın yapılandırıcısı");
        }
    }
    class B : A {
        public B() {
            Console.WriteLine("Bu da türetilmiş sınıfın yapılandırıcısı");
        }
    }
static void Main(string[] args)
        {
            B b = new B();
        }

Bu programın çıktısı, tahmin edeceğiniz üzere aşağıdaki gibi olur (çıktı sırasına dikkat ediniz. önce temel sınıfın yapılandırıcısı çağrılmakta):

Bu temel sınıfın yapılandırıcısı
Bu da türetilmiş sınıfın yapılandırıcısı

Peki kalıtım hiyerarşisi daha çok seviyeli olduğu zaman ne olur? Örneğin; class C : B {} olursa? Bu durumda da yine en tepedeki hiyerarşiden başlayarak aşağı doğru yapılandırıcılar çağrılır.

Yukardaki örneğe ekleme yapalım.

 class A{
        public A() {
            Console.WriteLine("A'nın yapılandırıcısı");
        }
    }

    class B : A {
        public B() {
            Console.WriteLine("B'nin yapılandırıcısı");
        }
    }

    class C : B {
        public C() {
            Console.WriteLine("C'nin yapılandırıcısı");
        }
    }

static void Main(string[] args){
            C c = new C();
}

Tahmin edeceğiniz üzere çıktı aşağıdaki gibi olur:

A'nın yapılandırıcısı
B'nin yapılandırıcısı
C'nin yapılandırıcısı


Peki daha karmaşık yapılandırcılarımızın olduğunu varsayalım. Bu durumda türetilmiş sınıf, temel sınıfın yapılandırıcısını çağırabilir. Zaten OOP'un kurallarından biri de mümkün mertebe bir kodu bir yerde yazmak ve defalarca çağırabilmek, dolayısıyla hataları mimimuma indirgemektir. Türetilmiş sınıf, temel sınıfın yapılandırıcısını çağırırsa temel sınıfın yaptığı ekstra işlerden kurtulmuş olur. Ancak türetilmiş sınıf kendine özgü işleri yerine getirecekse, bunu ayrıca deklare etmelidir. Peki temel sınıfın yapılandırıcısını nasıl çağıracağız? Bunu base anahtar sözcüğü ile halledeceğiz. Daha fazla laf kalabalığı yapmadan sözü aşağıdaki örneğe bırakalım:

    class IkiBoyutluSekil
    {
        public IkiBoyutluSekil(double _genislik, double _yukseklik) {
            this.Genislik = _genislik;
            this.Yukseklik = _yukseklik;
        }

        double genislik;
        double yukseklik;

        public double Genislik
        {
            get { return genislik; }
            set { genislik = value; }
        }
        public double Yukseklik
        {
            get { return yukseklik; }
            set { yukseklik = value; }
        }
    }

    class Ucgen : IkiBoyutluSekil {

        string isim;
        public string Isim
        {
            get { return isim; }
            set { isim = value; }
        }

        public Ucgen(double _genislik, double _yukseklik, string _isim) : base(_genislik, _yukseklik) {
            this.Isim = _isim;
        }

        public double Alan() {
            return Genislik * Yukseklik / 2;
        }     
    } 

static void Main(string[] args)
        {
            Ucgen ucgen = new Ucgen(10, 20, "üçgen");
            Console.WriteLine("Şeklin adı: " + ucgen.Isim);
            Console.WriteLine("Şeklin alanı: " + ucgen.Alan());
        }

Bu kodun çıktısı aşağıdaki gibi olacaktır:

Şeklin adı: üçgen
Şeklin alanı: 100

Bu kodu incelemek gerekirse; Ucgen sınıfı IkiBoyutluSekil sınıfından türemiştir (class Ucgen : IkiBoyutluSekil {....}). IkiBoyutluSekil temel sınıf olup kendi yapılandırıcısına sahiptir. Ucgen sınıfı ise IkiBoyutluSekil sınıfının yapılandırıcısını kullanmaktadır. Burada base anahtar sözcüğüne, konumuna ve kullanım şekline dikkat ediniz. IkiBoyutluSekil sınıfı Genislik ve Yukseklik propertieslerine ilk değer ataması yapıyor. Ucgen sınıfı ise base(_genislik, _yukseklik) ile temel sınıfın yapılandırıcısını çağırarak tekrar tekrar ilk değer ataması yapmıyor. Zaten IkiBoyutluSekil sınıfı bunu yapıyordu. Böylece Ucgen sınıfı bu yükten kurtulmuş oldu.

Bir başka konuya değinmek gerekirse;

Kalıtımda Ad Gizleme

Kalıtım hiyerarşisinde temel sınıf ile aynı ada sahip değişkenler tanımlamak mümkündür. Bu durumda temel sınıftaki değişken gizlenmiş olup, türetilmiş sınıftaki değişken geçerli olacaktır. Ad gizleme işlemini yapmak istediğimiz değişkenin başına new anahtar sözcüğünü eklemeliyiz.

Aşağıdaki basit örnek ad gizleme kavramını anlatmaktadır.

  class A
    {    
        public int x = 10;
    }

    class B : A {

        new int x = 11; //A'daki x'i gizledik

        public B() {
            Console.WriteLine(x);
        }
    }

B b = new B(); dediğimizde çıktımız "11" olacaktır. Tanımlara dikkat ediniz.

Bu işlemin tam tersi de mümkündür. Bir değişken türetilmiş sınıfta gizlenebildiği gibi, temel sınıf içindeki değişken de açığa çıkarılabilir. Bunun için base anahtar sözcüğünü kullanacağız.

Aşağıdaki örneği inceleyelim:

class A
    {    
        public int x = 10;
    }

    class B : A {

        new int x = 11;

        public B() {

            int a = base.x; //bu A'nın içindeki x
            int b = x; //bu B'nın içindeki x

            Console.WriteLine("A'nın içindeki x: " + a);
            Console.WriteLine("B'nın içindeki x: " + b);
        }
    }


B b = new B(); dediğimizde çıktımız

A'nın içindeki x: 10
B'nın içindeki x: 11

olacaktır. base'in kullanımına dikkat ediniz.

Bu yazıyı şimdilik burda noktalıyoruz. Anlaşılmayan bir konu varsa yorumlar kısmında yazabilirsiniz.

Bir sonraki yazıda Kalıtımda Overriding konusunu ele alacağız.

Bir sonraki yazıda buluşuncaya dek sağlıcaklakalın...

Paylaş:

1 yorum:

Bu Blogda Ara