Showing posts with label override. Show all posts
Showing posts with label override. Show all posts

Wednesday, October 31, 2012

Sanal Metotlar Örneği (c#)


Temel Ev Sınıfı:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

   /*kalitimda türetilen classların namespaceleri aynı olması tek bir referans üzerinden erişmemiz için kolaylık 
      sağlar.*/
namespace emlakci
{
    public class Ev
    {
        private int odasayisi;
        public int Odasayisi
        {
            get { return odasayisi; }
            set { odasayisi = value; }
        }
        private int katno;

        public int Katno
        {
            get { return katno; }
            set { katno = value; }
        }
        private int alan;

        public int Alan
        {
            get { return alan; }
            set { alan = value; }
        }
        private string semt;

        public string Semt
        {
            get { return semt; }
            set { semt = value; }
        }

        public Ev()
        {
        }
        public Ev(int odasayisi, int katno, string semt, int alan)
        {
            this.odasayisi = odasayisi;
            this.katno = katno;
            this.semt = semt;
            this.alan = alan;
        }

        /* virtual sanal anlamına gelir. virtual tanımlanan metotlar override ile tanımlanan metotlar tarafından 
          ezilebilir.*/
        public virtual string EvGoruntule()
        {
            return string.Format(" Odasayisi: {0} Katno: {1} Alan: {2} Semt: {3}", odasayisi, katno, alan, semt);
        }
    }
}


Türeyen Satılık Ev Sınıfı:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/*kalitimda türetilen classların namespaceleri aynı olması tek bir referans üzerinden erişmemiz için kolaylık sağlar.*/
namespace emlakci
{
    public class satilikev : Ev
    {
        private int fiyat;

        public int Fiyat
        {
            get { return fiyat; }
            set { fiyat = value; }
        }
        private int kapora;

        public int Kapora
        {
            get { return kapora; }
            set { kapora = value; }
        }

        public satilikev(int odasayisi, int katno, int alan, string semt, int fiyat, int kapora) : base()
        {
            base.Alan = alan;
            base.Katno = katno;
            base.Semt = semt;
            base.Odasayisi = odasayisi;
            this.fiyat = fiyat;
            this.kapora = kapora;
        }

        /*override ezmek anlamına gelir. Base sınıfındaki virual tanımlanmış metodun yerine önceliği alır. Artık
          virtual metot yerine aktif
         * olan sınıf override sınıfı olur. base sınıfındaki virtual metodu yerine öncelikli olarak override sınıflarla 
           işlem yapılır. eğer 
         * override sınıfı bulunmaz ise virtual sınıf ile işleme devam edilir. */
        /* override tanımladığımız metot türetilen sınıftaki virtual metodu yerine çağrışır. bir anlamda virtual 
           metodunu ezer. */

        public override string EvGoruntule()
        {
            return base.EvGoruntule() + " Fiyat: " + fiyat +  " Kapora: " + kapora;
        }
    }
}

Türetilen Kiralık Ev Sınıfı:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/*kalitimda türetilen classların namespaceleri aynı olması tek bir referans üzerinden erişmemiz için kolaylık sağlar.*/
namespace emlakci
{
    public class kiralikev:Ev
    {
        public kiralikev()
        {
        }

        public kiralikev(int odasayisi, int katno, int alan, string semt, double kira) : base(/*aşağıdaki tanımları 
                                                                                                                              burada yapabilirdik.*/)
        {
           /*yukarıdaki boş base constructori dolu olsaydı tekrardan base ile ataması yapmamıza gerek 
             kalmayacaktı. */
           base.Odasayisi = odasayisi;
           base.Katno = katno;
           base.Alan = alan;
           base.Semt = semt;
           this.kira = kira;
         
        }

        public double kira;
        public double depozito;

        /*override ezmek anlamına gelir. Base sınıfındaki virual tanımlanmış metodun yerine önceliği alır. Artık 
         virtual metot yerine aktif
         * olan sınıf override sınıfı olur. base sınıfındaki virtual metodu yerine öncelikli olarak override sınıflarla 
            işlem yapılır. eğer 
         * override sınıfı bulunmaz ise virtual sınıf ile işleme devam edilir. */
        /* override tanımladığımız metot türetilen sınıftaki virtual metodu yerine çağrışır. bir anlamda virtual 
         metodunu ezer. */
        public override string EvGoruntule()
        {
            return base.EvGoruntule() + " Kira " + kira + " Depozito: " + depozito;
        }
    }
}




Main Sınıfı:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using emlakci;

//Not: base sınıf üzerinden kalıtım sınıflarına erişebilme:

namespace kalitimsinifi
{
    class Program
    {
        static void Main(string[] args)
        {
            /*kalitim tüm sınıfları base sınıf üzerinden kullanabilme imkanı verir.
            fakat o sınıflara has alanı görmek için gerçek tipine cast etmemiz gereklidir. */

            Ev ev1 = new kiralikev(1, 1, 1, "1", 1);
            Ev ev2 = new satilikev(2, 2, 2, "2", 2, 2);
            Ev ev3 = new kiralikev(3, 3, 3, "3", 3);
            Ev ev4 = new satilikev(4, 4, 4, "4", 4, 4);
            kiralikev ev5 = new kiralikev(5, 5, 5, "5", 5);
            satilikev ev6 = new satilikev(6, 6, 6, "6", 6, 6);

            Ev[] evler = new Ev[6];
            evler[0] = ev1;
            evler[1] = ev2;
            evler[2] = ev3;
            evler[3] = ev4;
            evler[4] = ev5;
            evler[5] = ev6;
         
            for (int i = 0; i < evler.Length; i++)
            {
                Console.WriteLine(evler[i].EvGoruntule());

                if (evler[i] is kiralikev)
                {
                   /* kiralikev sinifindan bir nesne tanımlıyoruz ve bu nesneye evler[i] nesnesini (kiralikev) 
                    operatörüyle casting edip atıyoruz.)*/

                   kiralikev ke = (kiralikev)evler[i];

                   /* NOT: (evler[i] as kiralikev).depozito deyimi casting ile aynı görevi görür. */
                   Console.WriteLine(" depozito: "+ ke.depozito);
                }
            }

            Console.ReadLine();
        }

    }
}

Sanal Metotlar (c#)


Şu ana kadar bir nesne üzerinden çağırdığımız metotların tamamı derleme zamanında belirgindi. Yani derleme
aşamasında hangi nesne üzerinden hangi metotların çaığrabileceği belliydi. Sanal metotlar yardımıyla çalışma
zamanında metot seçme işinin nasıl olduğunu inceleyeceğiz.

Sanal metotlar temel sınıflar içinde bildirilmiş ve türeyen sınıflar içinde de tekrar bildirilen metotlardır.
Sanal metotlar nesne yönelimli programlama tekniğindeki çok biçimliliği(polimorphism) uygulayan yapılardır.
Temel sınıfta bir sanal metot bildirildiğinde bu temel sınıflar, temel sınıftaki sanal metodu devre dışı bırakarak
kendi metot gövdelerini oluşturabilirler.

Sanal metotlar sayesinde Temel sınıf türünden bir referansa türeyen sınıf referansları aktarıldığında, temel
sınıf referansı üzerinden kendisine aktarılan türeyen sınıfın sanal metodu çağrılabilir. Eğer türeyen sınıf
sanal metodu devre dışı bırakmamış ise temel sınıftaki sanal metot çağrılır. Çağrılan metodun hangi türe ait
olduğu çalışma zamanında belirlenir. Metotların bu şekilde çalışma zamanında belirlenmesine geç bağlama
(late binding) denilmektedir.

Sanal metotlar virtual anahtar sözcüğü kullanılarak bildirilir. Bu anahtar sözcük, metot bildirimin başına
eklenirse soyut metotlar bildirilmiş olur. Türeyen sınıfta, temel sınıftaki soyut netotları devre dışı
bırakmak için ise override anahtar sözcüğü kullanılır.


Sanal metotların etkin kullanılığı bir örnek;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SanalMetotlar
{
    class Memeli
    {
        public double Boy;
        public double Agirlik;

        public Memeli(double boy, double agirlik)
        {
            this.Boy = boy;
            this.Agirlik = agirlik;
        }

        virtual public void Konus()  /* Türetilen sınıflar ile işlem yapılacağı zaman, Konus() metodu 
                                    türetilen sınıfta override anahtar sözcüğü ile tanımlanmış ise
                                                   Türetilen sınıftaki metot çağıralacak. */
        {
            Console.WriteLine("ben konusamam");
        }
    }

    class kedi : Memeli
    {
        public string Turu;
        public kedi(string turu, int boy, int agirlik)
            : base(boy, agirlik)
        {
            this.Turu = turu;
        }

        override public void Konus()  /* Kedi sınıfı ile işlem yapılacağı zaman Base sınıftaki virtual ile
                                tanımlanan Konus() metodu yerine buradaki konus() metodu çağıralacak.*/
                               
        {
            Console.WriteLine("Ben bir kediyim");
        }
    }

    class koyun : Memeli
    {
        public string Turu;
        public koyun(string turu, int boy, int agirlik)   : base(boy, agirlik)  /* alınan değerleri türetilen sınıftaki  
                                                          değişkenlere gönderiyor. Base.Boy  tanımlamamıza gerek kalmıyor */
        {
            this.Turu = turu;
        }

        override public void Konus() /* Koyun sınıfı ile işlem yapılacağı zaman Base sınıftaki virtual ile
                                tanımlanan Konus() metodu yerine buraki konus() metodu çağıralacak.*/
        {
            Console.WriteLine("Ben bir koyunum");
        }
    }

    class MainMetodu
    {
        static void Main()
        {
            Memeli memeli1 = new Memeli(20, 30);
            kedi kedi1 = new kedi("Van", 10, 15);
            koyun koyun1 = new koyun("keçiören", 60, 80);

            memeli1.Konus();


            memeli1 = kedi1;
            memeli1.Konus();


            memeli1 = koyun1;
            memeli1.Konus();

           

            Console.ReadLine();

        }
    }
}

ekran çıktısı;

ben konusamam
ben kediyim
ben koyunum  

 Şeklinde olacaktır. Kedi ve Koyun nesneleri ait referans aktarılmasına rağmen çalışma zamanında bu Memeli
 referansı üzerinden Konus() metodunu çağırdığımızda Memeli sınıfındaki Konus() metodu yerine kendisine
 atanan sınıflara ait Konus() metotları çağrılmıştır.

 Sanal metotlar sayesinde temel sınıf referanslarına türeyen sınıf referansları atandığında, temel sınıf
 referansı üzerinden türeyen sınıfa ait metotları çağırabilmekteyiz. Bu yöntemle sadece temel sınıfta sanal
 olarak bildirilmiş metotların türeyen sınıfta devre dışı bırakılmış olan metotlara erişilebilir.