ÖNEMLİ : Kendim için aldığım notlar. Umarım size de bir faydası olur. Kullanılan her bir makale referans olarak eklenmiştir.

Java’da Kalıtım(inheritance) ve Java’da Polimorfizm Serisi


  1. Java’da Polimorfizm 1 - Amaç?
  2. Java’da Polimorfizm 2 - İzlenecek Kurallar Nelerdir?
  3. Java’da Polimorfizm 3 - Casting
  4. Java’da Polimorfizm 4.1 - Statik ve Dinamik Bağlanma 1
  5. Java’da Polimorfizm 4.2 - Statik ve Dinamik Bağlanma 2
  6. Java’da Polimorfizm 4.3 - Dinamik Bağlanma Örnek
  7. Java’da Polimorfizm 5 - Soyut(Abstract) Sınıflar ve Arayüzler(Interfaces)

Genel Bakış

Önceki bölümün devamı niteliğinde olan bu bölüm, statik ve dinamik bağlanma konusunun anlaşılmasını daha da artıracak.

Şimdi aşağıdaki gibi bir sınıf hiyerarşimizin olduğunu düşünelim.


Java Static and Dynamic Binding (Java Statik ve Dinamik Bağlama)

Görüleceği üzere Person sınıfı hiyerarşimizin en üstünde yer alan bir sınıftır, ve iki adet metodu bulunmaktadır. Onun hemen altında ise bu sınıfı miras alan bir Student sınıfını görmektesiniz. Anlaşılacağı üzere bu sınıf, Person sınıfının 2 metodunu geçersiz kılmış(override). Student sınfını da Undergrad isimli başka bir sınıf miras alıyor ama bu sınıf Student sınıfının sadece method2() metodunu geçersiz kılıyor.

Şimdi aşağıdaki gibi bir kod bloğunu çalıştırmak istesek sizce nasıl bir sonuç alırız?

1
2
3
4
5
6
7
8
public class Person {
    public void method1() {
        System.out.print("Person 1 ");
    }
    public void method2() {
        System.out.print("Person 2 ");
    }
}
1
2
3
4
5
6
7
8
9
10
public class Student extends Person {
    public void method1() {
        System.out.print("Student 1 ");
        super.method1();
        method2();
    }
    public void method2() {
        System.out.print("Student 2 ");
    }
}
1
2
3
4
5
public class Undergrad extends Student {
     public void method2() {
         System.out.print("Undergrad 2 ");
     }
}
1
2
Person u = new Undergrad();
u.method1();

Şimdi aşama aşama ilerleyelim istiyorum.

  1. Yukarıdaki kodun ilk satırında, kod çalışma zamanına geçtiğinde u referansının heap alanında Undergrad nesnesine bağlanacağını görüyoruz. O zaman şunu rahatlıkla söyleyebiliriz ki u referansı Undergrad nesnesini temsil etmektedir.
  2. u.method1(); referansımız haliyle method1 isimli metodu ilk arayacağı yer Undergrad sınıfı olacaktır. Yalnız Undergrad sınıfımızda böyle bir metodun olmadığını görüyoruz. Peki Java bu durumda ne yapacak?
  3. Java ilk olarak ilgili sınıfın miras aldığı bir sınıfın olup olmadığını kontrol eder.

    1
    
     public class Undergrad extends Student{...}
    

    Undergrad sınıfımız Student sınıfını miras aldığını görüyoruz. Java bu metodu bir de bu sınıfta arayacaktır.

  4. Burada method1 isimli yöntemi görmektesiniz. Şimdi bu yordamın içine girebiliriz. Kaşımıza ilk olarak

    1
    
     System.out.print("Student 1 ");
    

    ifadesi çıkmaktadır. Haliyle ekrana yazdıracağımız ilk şey bu olacaktır.

  5. super.method1(); sonrasında bu ifade ile karşılaşıyoruz. Aslında kafa karıştırıcı asıl bölüm burası!! sizce super anahtar kelimesi Undergrad sınıfını mı temsil ediyor, yoksa Person sınıfını mı temsil ediyor? Cevabımız Person sınıfı olacak!! Peki neden? Statik ve dinamik bağlanma konusu tam da burada devreye giriyor. Student sınıfındaki "super.method1()" çağrısı derleme zamanında çözülür, bu nedenle asıl çağıran nesne Undergrad sınıfına ait olsa da, Student sınıfındaki super anahtar kelimesi statik bağlandığından Person sınıfını ifade eder. Yani daha derleme zamanında java, Student sınıfında bu super anahtar kelimesini farkeder ve bu sınıfın miras aldığı sınıfı arar. Ve burada derleme zamanında statik bağlamayı gerçekleştirir.
  6. Şimdi de Student sınıfının miras aldığı Person sınıfındaki method1() yöntemine gireceğiz. Burada bir adet yazdırma ifadesi bulunmaktadır.

    1
    
     System.out.print("Person 1 ");
    

    Bu işlemi de gerçekleştirdikten sonra tekrardan Student sınıfında kaldığımız yere geri döneriz. Sıradaki çağrı method2(); bu şekilde verilmiş. Sanki bir çağıran nesne(calling object) yok gibi anlaşılabilir.

  7. Daha önceki derslerden de hatırlayacağımız gibi java bu gibi ifadelerle karşılaştığında arka planda kendi bir this ifadesi ekleyecektir. Yani javanın bu ifadeden aslında anladığı şudur. this.method2();
  8. Peki this anahtar kelimesi ile kastedilen hangi metotdur? Student sınıfı içindeki method2() mi? Person sınıfı içindeki method2() mi yoksa Undergrad sınıfı içindeki method2() yordamı mıdır? Cevap Undergrad sınıfıdır. Çünkü this anahtar kelimesi her zaman çalışma zamanındaki nesneyi yani başta asıl çağrılan nesneyi ifade eder. Buradaki çalışma zamanı nesnemizin Undergrad olduğunu biliyoruz. Bu sebepten bu metodu ilk olarak Undergrad sınıfı içerisinde aramalıyız. Bulamazsak başta olduğu gibi miras aldığı sınıflara bakabiliriz. Ancak Undergrad sınıfı içinde zaten bu metodun olduğunu görüyoruz.
  9. Undergrad sınıfı içindeki method2() yordamı

    1
    
     System.out.print("Undergrad 2 ");
    

    ifadesini yazdırmamızı istiyor. Sonuç olarak ekranda şu şekilde bir çıktı karşılaşırız.

1
Student 1 Person 1 Undergrad 2

ÖZET

  • super anahtar kelimesi ile yapılan çağrıların bağlanması(vehahut haritalanması da diyebiliriz) derleme zamanında gerçekleşir. Java super çağrısının bulunduğu sınıfı derleme zamanında haritalar ve doğrudan super çağrısının yapıldığı metodu bir üst sınıfta arar.
  • this anahtar kelimesi ile yapılan metot çağrıları ise çalışma zamanında bağlanır. Yani Java aslında, çalışma zamanında nesnenin gerçek türünü kullanacaktır.

Referanslar