Previous
Next

JAVA - Late Binding(Geç Bağlama) ve Early Binding(Erken Bağlama) nedir?

by Cem Kefeli 29. Eylül 2009 07:03

JavaDaha önce buradaki yazımda polimorfizm(çok biçimlilik) konusunda bilgi verirken late binding(geç bağlama) konusundan söz açılmıştı aslında. Çünkü geç bağlama kavramı çok biçimliliğin doğal bir sonucu olarak ortaya çıkmaktadır. Yani çok biçimliliğin olmadığı bir yerde geç bağlamadan söz etmek olanaksızdır. Geç bağlamayı en genel olarak çok biçimliliğin oluştuğu anda, yani run time(çalışma zamanı) sırasında, nesne örneğinin bağlanacağı nesne türünün belirlenmesi ve buna uygun işlemlerin tamamlanması sürecinde yapılan işler olarak tanımlayabilirim. Güzel tanım oldu :) Fakat birçoğumuz için birşey ifade etmediği de çok açık. Şimdi sıra bu hipotezimizin içini doldurmaya geldi. Bu hipotezin içini doldurabilmek için "Polymorphism(Çok biçimlilik) nedir?" başlıklı yazımın içerisindeki nesne yapılarından ve kalıtım şemasından faydalanacağım. Kalıtım demişken, kalıtım ile ilgili buradaki yazımı da okuyarak az sonra anlatacaklarıma alt yapı oluşturabilirsiniz. Bu konuları anlamanızı öneriyorum çünkü kalıtımın olmadığı yerde çok biçimlilikten, çok biçimliliğin olmadığı yerde de geç bağlamadan söz etmek olanaksızdır.

Late Binding UMLSağ tarftaki UML diagramında bir kalıtım yapısı bulunmakta. KISI ana sınıfından PERSONEL isimli yeni bir sınıf ve PERSONEL sınıfındanda da MUHENDIS ve TEKNISYEN olmak üzere iki farklı sınıf türetilmiştir. MUHENDIS ve TEKNISYEN bir PERSONEL'dir. PERSONEL ise bir KISI'dir türünde ifadelerin kurulabildiği her yerde kalıtımdan söz etmek mümkündür. Böylece bu nesnelerin arasında artık kalıtımı ilişkisi kurulmuş olur. PERSONEL sınıfı KISI sınıfında yer alan BenKimim isimli fonksiyonu override etmiş yani geçersiz kılmıştır. Bu fonksiyon için kendisi bir içerik oluşturmuştur. Aynı şekilde MUHENDIS ve TEKNISYEN sınıfları da kendi içeriklerini BenKimim fonksiyonu içerisine yerleştirmiştir. Sınıfların tanımlamalarını da aşağıda vermekteyim.

Main.java  |  Netbeans Projesini indir LateBinding1.rar (14,52 kb)  |  Gizle  |  Göster
package latebinding1;
 
 /**
 *
 * @author Cem KEFELI
 * http://www.cemkefeli.com
 */
public class Main
{
    static public class KISI
    {
        public void BenKimim()
        {
            System.out.println("Ben herhangi bir kisiyim.");
        }
    }
    static public class PERSONEL extends KISI
    {
        @Override
        public void BenKimim()
        {
            System.out.println("Ben bir personelim.");
        }
    }
    static public class MUHENDIS  extends PERSONEL
    {
        @Override
        public void BenKimim()
        {
            System.out.println("Ben bir mühendisim.");
        }
    }
    static public class TEKNISYEN  extends PERSONEL
    {
        @Override
        public void BenKimim()
        {
            System.out.println("Ben bir teknisyenim.");
        }
    }
    static public void KimimOnuYaz(KISI Birisi)
    {
        Birisi.BenKimim();
    }
    public static void main(String[] args) 
    {
        KISI Insan1=new KISI();
        PERSONEL Insan2=new PERSONEL();
        MUHENDIS Insan3=new MUHENDIS();
        TEKNISYEN Insan4=new TEKNISYEN();
        KimimOnuYaz(Insan1);
        KimimOnuYaz(Insan2);
        KimimOnuYaz(Insan3);
        KimimOnuYaz(Insan4);
    }
}	
Program Çıktısı

Polymorphism örnek 1KimimOnuYaz fonksiyonu parametre olarak yalnızca KISI sınıfı türünde değişkenleri kabul etmektedir. Fakat biz bu fonksiyon içerisine her dört sınıfın örneklerini de(KISI, PERSONEL, MUHENDIS, TEKNISYEN) gönderebildik ve herhangi bir hata ile de karşılaşmadık. Herhangi bir hata ile karşılaşmadığımız gibi üstüne üstlük çok güzel bir durum ile de karşılaştık. Peki bu iş nasıl oldu? Şöyle ki; ilk önce main fonksiyonu içerisinde dört sınıfa ait nesne örneklerimizi oluşturduk. sonrasında ilk önce KISI türünden Insan1 referansını KimimOnuYaz isimli fonksiyona gönderdik. Burada bir tuhaflık yok, çünkü KimimOnuYaz fonksiyonu zaten giriş parametresi olarak KISI nesnesini seviyor. Dolayısı ile KimimOnuYaz içerisindeki Birisi nesne örneğinin BenKimim fonksiyonu çağırılmış oldu. Birisi referansının türü KISI olduğu için KISI sınıfının BenKimim fonksiyonu çağırıldı. İkinci olarak ise Insan2 referansı KimimOnuYaz fonksiyonu tarafından giriş olarak alındı. İşte burada dikkat etmemiz gereken önemli bir nokta var. KimimOnuYaz fonksiyonu yalnızca KISI sınıfına ait nesne örneklerini kabul ettiği için tam bu satırda bir tür dönüşümü işlemi yapıldı. Bu işleme UpCasting adı verilmektedir. Yani tam olarak şu oldu aslında, KimimOnuYaz fonksiyonu içerisindeki KISI türünden Birisi nesnesi birçok kılığa birden bürünüverdi bir anda. Yeri geldi KISI nesne türünden bir nesne örneği oldu, yeri geldi TEKNİSYEN nesne türünden bir nesne örneği oluverdi bir anda. Birisi ismindeki nesne örneği kendi sınıfı olan KISI ve KISI sınıfından türeyen diğer nesne örneklerine bağlanabildi. Sonuç olarak ise Birisi referansının nesne türü ne ise o nesneye ait BenKimim fonksiyonu çağırıldı. İşte size Polimorfizm!!! Peki bizim polimorfizm ile ne işimiz var ki, konumuz geç bağlama değil miydi diye soranlar için hemen cevap geliyor. Yazının başında da bahsettiğim gibi geç bağlamanın ortaya çıkış sebebi polimorfizm'dir. Dolayısı ile çok biçimliliğin olmadığı bir yerde geç bağlamadan söz etmek de mümkün değildir. Bu yüzden geç bağlama olayını iyi özümseyebilmek için çok biçimliliğin iyice sindirilmiş olması gerekmektedir. Peki ya geç bağlama bu olayın neresindedir? Aslında çok biçimliliğin oluştuğu an geç bağlamadan söz etmek mümkündür. Başlarda da tanımladığımız gibi geç bağlama, nesne referansının hangi nesneye bağlanacağına karar verildiği an(çalışma zamanı/run time) oluşur ve bu karar verme işlemi ile birlikte gerekli şeylerin yapılması sürecine denmektedir. Şimdi birçoğunuzun aklına şu soru gelecektir. İyi de burada zaten derleme anında(compile time) hangi nesnenin nereye bağlanacağı zaten bilinmektedir ki. Derleyici programcığımızı derlerken zaten böyle bir durum oluşup oluşamayacağına bakmıyor mu ki acaba? Çünkü KISI türünden nesne örneği kabul eden bir fonksiyona KISI türünden türeyen başka nesne örneklerinin gönderildiği zaten belli. Bu aslında oldukça kafaları bulandırıcı bir düşünce fakat yalnızca dikkat edilmesi gereken bir fonksiyonun beklemediği türden bir değişkene vereceği cevabın ne olduğunun araştırılmasıdır. Derleyiciler bu konu ile ilgilenmezler. Böyle bir durum yalnızca çalışma anında oluşabilir. Fakat bu sözlerimin yeterli gelmediği kişiler için aşağıdaki kusursuz örneği veriyorum. Nette yaptığınız araştırmaların çoğunda bu ve buna benzer örnekler göreceksiniz. Çünkü konuyu çok iyi pekiştiriyor.

Main.java  |  Netbeans Projesini indir LateBinding2.rar (14,80 kb)  |  Gizle  |  Göster
package latebinding2;
 /**
 *
 * @author Cem KEFELI
 * http://www.cemkefeli.com
 */
public class Main
{
    static public class KISI
    {
        public void BenKimim()
        {
            System.out.println("Ben herhangi bir kisiyim.");
        }
    }
    static public class PERSONEL extends KISI
    {
        @Override
        public void BenKimim()
        {
            System.out.println("Ben bir personelim.");
        }
    }
    static public class MUHENDIS  extends PERSONEL
    {
        @Override
        public void BenKimim()
        {
            System.out.println("Ben bir mühendisim.");
        }
    }
    static public class TEKNISYEN  extends PERSONEL
    {
        @Override
        public void BenKimim()
        {
            System.out.println("Ben bir teknisyenim.");
        }
    }
    static public void KimimOnuYaz(KISI Birisi)
    {
        Birisi.BenKimim();
    }
    public static void main(String[] args)
    {
        KISI Insan1=new KISI();
        PERSONEL Insan2=new PERSONEL();
        MUHENDIS Insan3=new MUHENDIS();
        TEKNISYEN Insan4=new TEKNISYEN();
        KISI[] Kisiler = new KISI[4];
        for( int i=0 ; i<4 ; i++ )
        {
            switch( (int)(Math.random()*4) )
            {
                case 0: Kisiler[i]=Insan1; break;
                case 1: Kisiler[i]=Insan2; break;
                case 2: Kisiler[i]=Insan3; break;
                case 3: Kisiler[i]=Insan4; break;
            }
        }
        for( int i=0 ; i<4 ; i++ )
        {
            KimimOnuYaz(Kisiler[i]);
        }
    }
}	
Program Çıktısı  |  Gizle  |  Göster
run:
Ben bir personelim.
Ben bir mühendisim.
Ben herhangi bir kisiyim.
Ben bir personelim.
BUILD SUCCESSFUL (total time: 0 seconds)
run:
Ben bir personelim.
Ben bir personelim.
Ben bir teknisyenim.
Ben bir teknisyenim.
BUILD SUCCESSFUL (total time: 0 seconds)
run:
Ben bir teknisyenim.
Ben bir mühendisim.
Ben bir personelim.
Ben herhangi bir kisiyim.
BUILD SUCCESSFUL (total time: 0 seconds)
run:
Ben herhangi bir kisiyim.
Ben bir teknisyenim.
Ben bir personelim.
Ben bir teknisyenim.
BUILD SUCCESSFUL (total time: 0 seconds)

Bu aşamada yukarıda verdiğim örneği inceleyecek olursanız 64. satırda çağırılan KimimOnuYaz isimli fonksiyona Kisiler isimli KISI nesne türünden tanımlanmış dizi değişkenin tüm elemanları sırası gönderilmektedir. Fakat üst satırlarda ise Kisiler isimli değişkenin tüm üyelerinin KISI türünden değil de KISI türünden türeyen farklı nesne türlerden olduklarını göreceksiniz. Burada bir rastgelelik durumu vardır. Yani rastgele bir sayı üretilmekte ve bu sayıya göre Kisiler dizi değişkeninin üyeleri belirlenmektedir. Yukarıdaki örnekteki derleme anında zaten bu durum biliniyordu çalışma anında neden karar verilsin ki gibi bir kafa karışıklığını bu örnek fazlası ile giderecektir. Çünkü rastgele sayıların değeri yalnızca çalışma anında belirlenebilmekte ve böylece hangi nesnenin türünün BenKimim fonksiyonunun çağırılacağı da çalışma anında ortaya çıkmaktadır. İşte geç bağlamanın güzel bir örneği...

Geç bağlamanın tam tersi ise erken bağlamadır(early binding). Erken bağlamada nesne referanslarının hangi nesneye bağlanacağının çalışma anında değil de derleme anında belirlenebilmesi olayına denmektedir. Burada çalışma anında bir karar verme işleminden söz edilemez.

Geç bağlama bize çok biçimliğin bir hediyesi ve çok biçimlilik gibi güzel bir şeyin sonucu ortaya çıkan bir kavramdır. Çok biçimliliğin güzelliklerinin yanında bize getirmiş olduğu bazı maliyetler de vardır tabi ki. Bu da geç bağlamanın oluştuğu an harcanan karar verme ve gerekli işlemleri yapmak için harcanan süre olarak göze çarpmaktadır.

Yorum ekle

biuquote
  • Yorum
  • Canlı önizleme
Loading

Hakkımda...

Cem KEFELİ

Electronics and
Telecommunication Eng.
devamı...


Son yapılan yorumlar...

Comment RSS

Yasal bir uyarı...

Disclaimer"Bu web sitesinde görmüş olduğunuz bilgilerin, dokümanların ve diğer materyallerin kullanılmasından doğabilecek hiç bir sorumluluktan site sahibi sorumlu tutulamaz. Web sitesi içerisinde yer alan yazılar, yorumlar, resimler ve diğer tüm içerikler yalnızca sahibinin görüşünü yansıtmakta olup içeriğin sahibi kişilerin çalıştığı kurumları bağlayıcı hiç bir nitelik taşımamaktadır. Yapılan tüm alıntılar mutlaka kaynak gösterilerek verilmeye çalışılmaktadır. Web sitesi içerisinde bulunan ilgili materyaller, ilgili yasal kurumlar tarafından uygun görülmemesi durumda kaldırılacaktır."
General