RunTime Polymorphism

(Dynamic Method Dispatch)

 

Overridden ve overloaded metotlar java’nın asıl gücünü ortaya koyan özeliklerdir. Overloded metotların çözümlenmesi derlenme aşamasında,  overridden metotların çözümlenmesi ise koşturma (runTime) aşamasında olur. Bir tek metot adıyla, birden çok farklı  metotları koşturma özeliğine, java’da polymorphism denir.   

Şu önemli özeliği biliyoruz. Bir üst sınıfın referansı (işaretçi, pointer) bir alt sınıfa ait nesneyi işaret edebilir. Java, bu özelliği kullanarak, run-time aşamasında hangi overridden metodu seçmesi gerektiğini bulur. Bunun nasıl olduğunu aşağıdaki örnek üzerinde anlatacağız. Bir overridden metot çağrılınca, o anda refere edilen nesne kim ise ona ilişkin metot çağrılmış olur. Başka bir deyişle, hangi overridden metodunun seçileceğine karar veren referansın (işaretçinin) kendisi değil, onun işaret ettiği nesnedir.

Liste 12:

Aşağıdaki program run-time polymorphismini göstermektedir.

 

                   // RunTime Polymorphism (Dynamic Method Dispatch)

class A {

   void kimGeldi() {

     System.out.println("Şimdi A ‘daki kimGeldi methodu çağrıldı.");

  }

}

 

class B extends A {

        // override kimGeldi()

  void kimGeldi() {

    System.out.println("Şimdi B ‘deki kimGeldi methodu çağrıldı. ");

  }

}

 

class C extends A {

        // override kimGeldi()

  void kimGeldi() {

    System.out.println("Şimdi C ‘deki kimGeldi methodu çağrıldı. ");

  }

}

 

class Dispatch {

  public static void main(String args[]) {

    A a = new A();    // A tipinden nesne

    B b = new B();    // B tipinden nesne

    C c = new C();    // C tipinden nesne

    A r;              // A tipinden bir referans (işaretçi, pointer)  

 

    r = a;            // r  referansı A ‘nın bir nesnesini işaret ediyor

    r.kimGeldi();     // A ' daki kimGeldi metodunu çağırıyor

 

    r = b;            // r  referansı B ‘nin bir nesnesini işaret ediyor

    r.kimGeldi();     // B ' deki kimGeldi metodunu çağırıyor

 

    r = c;            // r  referansı C ‘nin bir nesnesini işaret ediyor

    r.kimGeldi();     // C ' deki kimGeldi metodunu çağırıyor

  }

}

 

 

Bu program A üst-sınıfını ve onun B ve C alt-sınıflarını yaratıyor. A üst-sınıfındaki kimGeldi() metodu B ve C içinde ayrı ayrı override ediliyor. A tipinden nesneleri işaret etmek üzere r adlı bir referans (işaretçi, pointer) tanımlanıyor. r pointeri B ve C ye ait nesneleri de işaret edebilir. r referansı A nın bir nesnesini işaret ederken çağrılan r.kimGeldi() metodu A ‘daki kimGeldi() metodudur (7.-8. satırlar). r referansı B nin bir nesnesini işaret ederken çağrılan r.kimGeldi() metodu B ‘deki kimGeldi() metodudur (9.-10. satırlar). r referansı C nin bir nesnesini işaret ederken çağrılan r.kimGeldi() metodu C ‘deki  kimGeldi() metodudur (11.-12.satırlar).


Liste 13:

Aşağıdaki örnek, düzlemsel şekillerin alanlarını bulmak için “method overriding” özelliğinden yararlanmaktadır. Program Sekil adlı bir üst-sınıf  ile ona ait alan() adlı bir metot tanımlamaktadır. Burada metot hiçbir hesap yapmamaktadır. Ama, bu metot, Ucgen ve Dikdörgen adlı alt-sınıflarda örtülerek (overriding) edilerek bu şekillerin alanlarını hesaplayacak biçime sokulmaktadır. Öte  yandan Sekil’i işaret eden referans değişkeni bir  Ucgen nesnesini işaret ederken o üçgenin alanı, bir Dikdotgen nesnesini işaret ederken o dikdörtgenin alanı hesaplanabilmektedir.

        // run-time polymorphism.

class Sekil {

  double boyut1;

  double boyut2;

 

  Sekil(double a, double b) {

    boyut1 = a;

    boyut2 = b;

  }

 

  double alan() {

    System.out.println("Şeklin alanı henüz tanımlı değil! ");

    return 0;

  }

}

 

class Dikdortgen extends Sekil {

  Dikdortgen(double a, double b) {

    super(a, b);

  }

 

        // Dikdörtgen için override alan

  double alan() {

    System.out.println("Dikdörtgenin alanı.");

    return boyut1 * boyut2;

  }

}

 

class Ucgen extends Sekil {

  Ucgen(double a, double b) {

    super(a, b);

  }

 

        // Üçgen için override alan

  double alan() {

    System.out.println("Üçgenin alanı.");

    return boyut1 * boyut2 / 2;

  }

}

 

class AlanBul {

  public static void main(String args[]) {

    Sekil f = new Sekil(15, 15);

    Dikdortgen r = new Dikdortgen(7, 4);

    Ucgen t = new Ucgen(9, 6);

   

    Sekil ref;

 

    ref = r;

    System.out.println("Alan = " + ref.alan());

   

    ref = t;

    System.out.println("Alan = " + ref.alan());

   

    ref = f;

    System.out.println("Alan = " + ref.alan());

  }

}

 

Soru: Yukarıdaki programda alan tanımı Sekil sınıfı içinde yapılsa ne olurdu. Deneyiniz.