Java - Polimorfizm

Polimorfizm, bir nesnenin birçok form alma yeteneğidir. OOP'de polimorfizmin en yaygın kullanımı, bir alt sınıf nesnesine başvurmak için bir ana sınıf başvurusu kullanıldığında ortaya çıkar.

Birden fazla IS-A testini geçebilen herhangi bir Java nesnesi polimorfik olarak kabul edilir. Java'da, herhangi bir nesne kendi türü ve Object sınıfı için IS-A testini geçeceğinden tüm Java nesneleri çok biçimlidir.

Bir nesneye erişmenin tek olası yolunun bir referans değişkeni aracılığıyla olduğunu bilmek önemlidir. Bir referans değişkeni yalnızca tek tipte olabilir. Bir kez bildirildikten sonra, bir referans değişkeninin türü değiştirilemez.

Referans değişkeni, nihai olarak bildirilmemesi koşuluyla diğer nesnelere yeniden atanabilir. Referans değişkeninin türü, nesnede başlatabileceği yöntemleri belirleyecektir.

Bir referans değişkeni, bildirilen türündeki herhangi bir nesneye veya bildirilen türünün herhangi bir alt türüne başvurabilir. Bir referans değişkeni, bir sınıf veya arabirim türü olarak bildirilebilir.

Misal

Bir örneğe bakalım.

public interface Vegetarian{}
public class Animal{}
public class Deer extends Animal implements Vegetarian{}

Şimdi, Deer sınıfı, çoklu kalıtıma sahip olduğu için polimorfik olarak kabul edilir. Aşağıdakiler, yukarıdaki örnekler için geçerlidir -

  • Bir Geyik Bir Hayvandır
  • Bir Geyik Vejetaryendir
  • Bir Geyik, Bir Geyik
  • Bir Geyik Bir Nesnedir

Referans değişken olguları bir Deer nesne referansına uyguladığımızda, aşağıdaki beyanlar yasaldır -

Misal

Deer d = new Deer();
Animal a = d;
Vegetarian v = d;
Object o = d;

Tüm referans değişkenleri d, a, v, o, yığındaki aynı Deer nesnesine başvurur.

Sanal Yöntemler

Bu bölümde, Java'daki geçersiz kılınan yöntemlerin davranışının, sınıflarınızı tasarlarken polimorfizmden nasıl yararlanmanızı sağladığını göstereceğim.

Bir çocuk sınıfın, üst sınıfındaki bir yöntemi geçersiz kılabildiği yöntemi geçersiz kılmayı zaten tartışmıştık. Geçersiz kılınan bir yöntem, esas olarak üst sınıfta gizlidir ve alt sınıf geçersiz kılma yönteminde super anahtar sözcüğü kullanmadıkça çağrılmaz.

Misal

/* File name : Employee.java */
public class Employee {
   private String name;
   private String address;
   private int number;

   public Employee(String name, String address, int number) {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }

   public void mailCheck() {
      System.out.println("Mailing a check to " + this.name + " " + this.address);
   }

   public String toString() {
      return name + " " + address + " " + number;
   }

   public String getName() {
      return name;
   }

   public String getAddress() {
      return address;
   }

   public void setAddress(String newAddress) {
      address = newAddress;
   }

   public int getNumber() {
      return number;
   }
}

Şimdi, Employee sınıfını aşağıdaki gibi genişlettiğimizi varsayalım -

/* File name : Salary.java */
public class Salary extends Employee {
   private double salary; // Annual salary
   
   public Salary(String name, String address, int number, double salary) {
      super(name, address, number);
      setSalary(salary);
   }
   
   public void mailCheck() {
      System.out.println("Within mailCheck of Salary class ");
      System.out.println("Mailing check to " + getName()
      + " with salary " + salary);
   }
   
   public double getSalary() {
      return salary;
   }
   
   public void setSalary(double newSalary) {
      if(newSalary >= 0.0) {
         salary = newSalary;
      }
   }
   
   public double computePay() {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
}

Şimdi, aşağıdaki programı dikkatlice inceleyin ve çıktısını belirlemeye çalışın -

/* File name : VirtualDemo.java */
public class VirtualDemo {

   public static void main(String [] args) {
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
      System.out.println("Call mailCheck using Salary reference --");   
      s.mailCheck();
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
   }
}

Bu, aşağıdaki sonucu verecektir -

Çıktı

Constructing an Employee
Constructing an Employee

Call mailCheck using Salary reference --
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0

Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.0

Burada iki Salary nesnesini somutlaştırıyoruz. Maaş referansı kullanan kişisve diğeri bir Çalışan referansı kullanarak e.

S.mailCheck () çağrılırken , derleyici derleme zamanında Salary sınıfında mailCheck () 'i görür ve çalışma zamanında Salary sınıfında mailCheck ()' i çağırır.

mailCheck () açık e oldukça farklı çünkü eÇalışan referansıdır. Derleyici e.mailCheck () öğesini gördüğünde , derleyici Employee sınıfında mailCheck () yöntemini görür.

Burada, derleme zamanında derleyici bu ifadeyi doğrulamak için Employee'de mailCheck () kullanmıştır. Bununla birlikte, çalışma zamanında JVM, Salary sınıfındaki mailCheck () işlevini çağırır.

Bu davranışa sanal yöntem çağrısı adı verilir ve bu yöntemlere sanal yöntemler adı verilir. Derleme zamanında kaynak kodda kullanılan başvuru hangi veri türü olursa olsun, çalışma zamanında geçersiz kılınan bir yöntem çağrılır.