Java'da Dinamik ve Statik polimorfizm arasındaki farkı açıklayan basit bir örnek verebilir misiniz?
Java'da Dinamik ve Statik polimorfizm arasındaki farkı açıklayan basit bir örnek verebilir misiniz?
Yanıtlar:
Polimorfizm
1. Statik bağlama / Derleme Zamanı bağlama / Erken bağlama / Yöntem aşırı yükleme. (Aynı sınıfta)
2. Dinamik bağlama / Çalışma Zamanı bağlama / Geç bağlama / Yöntemi geçersiz kılma. (Farklı sınıflarda)
class Calculation {
void sum(int a,int b){System.out.println(a+b);}
void sum(int a,int b,int c){System.out.println(a+b+c);}
public static void main(String args[]) {
Calculation obj=new Calculation();
obj.sum(10,10,10); // 30
obj.sum(20,20); //40
}
}
class Animal {
public void move(){
System.out.println("Animals can move");
}
}
class Dog extends Animal {
public void move() {
System.out.println("Dogs can walk and run");
}
}
public class TestDog {
public static void main(String args[]) {
Animal a = new Animal(); // Animal reference and object
Animal b = new Dog(); // Animal reference but Dog object
a.move();//output: Animals can move
b.move();//output:Dogs can walk and run
}
}
Animal reference but Dog object
, neden kullanamıyoruz Dog reference and dog object
?
Yöntem aşırı yükleme, statik polimorfizmin bir örneği olabilir
oysa geçersiz kılma, dinamik polimorfizmin bir örneği olacaktır.
Çünkü, aşırı yükleme durumunda, derleme zamanında derleyici çağrıya hangi yöntemin bağlanacağını bilir. Bununla birlikte, dinamik polimorfizm için çalışma zamanında belirlenir
Dinamik (çalışma zamanı) polimorfizmi , çalışma zamanında var olan polimorfizmdir. Burada Java derleyicisi, derleme sırasında hangi yöntemin çağrıldığını anlamaz. Yalnızca JVM, çalışma zamanında hangi yöntemin çağrılacağına karar verir. Örnek yöntemlerini kullanarak yöntem aşırı yükleme ve yöntemi geçersiz kılma, dinamik polimorfizm örnekleridir.
Örneğin,
Farklı belge türlerini serileştiren ve serileştiren bir uygulama düşünün.
Temel sınıf olarak 'Belge'ye ve ondan türetilen farklı belge türü sınıflarına sahip olabiliriz. Örneğin XMLDocument, WordDocument vb.
Belge sınıfı, 'Serialize ()' ve 'De-serialize ()' yöntemlerini sanal olarak tanımlayacak ve türetilen her sınıf, bu yöntemleri belgelerin gerçek içeriğine bağlı olarak kendi yöntemiyle uygulayacaktır.
Farklı belge türlerinin serileştirilmesi / serileştirilmesi gerektiğinde, belge nesnelerine 'Belge' sınıf referansı (veya işaretçi) tarafından ve 'Serialize ()' veya 'De-serialize ()' yöntemi çağrıldığında başvurulacaktır. üzerine sanal yöntemlerin uygun sürümleri çağrılır.
Statik (derleme zamanı) polimorfizm , derleme zamanında sergilenen polimorfizmdir. Burada Java derleyicisi hangi yöntemin çağrıldığını bilir. Statik yöntemler kullanarak yöntem aşırı yükleme ve yöntemi geçersiz kılma; özel veya nihai yöntemler kullanarak yöntemi geçersiz kılma, statik polimorfizm örnekleridir
Örneğin,
Bir çalışan nesnesi, biri bağımsız değişken almayan ve diğeri çalışan verileriyle birlikte görüntülenecek bir önek dizesi alan iki print () yöntemine sahip olabilir.
Bu arabirimler göz önüne alındığında, print () yöntemi herhangi bir argüman olmadan çağrıldığında, derleyici, fonksiyon argümanlarına bakarak hangi fonksiyonun çağrılması gerektiğini bilir ve buna göre nesne kodunu üretir.
Daha fazla ayrıntı için lütfen "Polimorfizm Nedir" (Google it) okuyun.
Bağlama, yöntem çağrısı ve yöntem tanımı arasındaki bağlantıyı ifade eder.
Bu resim neyin bağlayıcı olduğunu açıkça göstermektedir.
Bu resimde, "a1.methodOne ()" çağrısı, karşılık gelen methodOne () tanımına bağlanıyor ve "a1.methodTwo ()" çağrısı, ilgili methodTwo () tanımına bağlı.
Her yöntem çağrısı için uygun yöntem tanımı olmalıdır. Bu, java'da bir kuraldır. Derleyici her yöntem çağrısı için uygun yöntem tanımını görmezse, hata verir.
Şimdi, java'da statik bağlama ve dinamik bağlamaya gelin.
Java'da Statik Bağlama:
Statik bağlama, derleme sırasında gerçekleşen bir bağlamadır. Erken bağlama olarak da adlandırılır çünkü bağlama, bir program gerçekten çalışmadan önce gerçekleşir
.
Statik bağlanma aşağıdaki resimdeki gibi gösterilebilir.
Bu resimde, 'a1', A sınıfı nesneye işaret eden A Sınıfı tipinde bir referans değişkenidir. 'A2' aynı zamanda A sınıfı bir referans değişkenidir, ancak B Sınıfı nesnesine işaret eder.
Derleme sırasında, bağlama sırasında, derleyici belirli bir referans değişkeninin işaret ettiği nesnenin türünü kontrol etmez. Sadece bir yöntemin çağrıldığı referans değişkeninin türünü kontrol eder ve bu türde onun için bir yöntem tanımı olup olmadığını kontrol eder.
Örneğin, yukarıdaki resimdeki “a1.method ()” yöntem çağrısı için derleyici, A Sınıfı'nda method () için yöntem tanımı olup olmadığını kontrol eder. Çünkü 'a1', A Sınıfı türüdür. Benzer şekilde, "a2.method ()" yöntem çağrısı için, A Sınıfında method () için yöntem tanımı olup olmadığını kontrol eder. Çünkü 'a2' aynı zamanda Sınıf A türüdür. "A1" ve "a2" nin hangi nesneyi işaret ettiğini kontrol etmez. Bu tür bağlama, statik bağlama olarak adlandırılır.
Java'da Dinamik Bağlama:
Dinamik bağlama, çalışma süresi sırasında gerçekleşen bir bağlamadır. Aynı zamanda geç bağlama olarak da adlandırılır çünkü bağlama, program gerçekten çalışırken gerçekleşir.
Çalışma süresi boyunca gerçek nesneler bağlama için kullanılır. Örneğin, yukarıdaki resimdeki "a1.method ()" çağrısı için, 'a1'in işaret ettiği gerçek nesnenin method ()' u çağrılacaktır. "A2.method ()" çağrısı için, 'a2'nin işaret ettiği gerçek nesnenin yöntemi () çağrılacaktır. Bu tür bağlama, dinamik bağlama olarak adlandırılır.
Yukarıdaki örneğin dinamik bağlanması aşağıdaki gibi gösterilebilir.
Java'da statik bağlama ve dinamik bağlama başvurusu
Çok Biçimlilik: Çok biçimlilik, bir nesnenin birçok biçim 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.
Dinamik Bağlama / Çalışma Zamanı Polimorfizmi:
Çalışma zamanı polimorfizmi, yöntemi geçersiz kılma olarak da bilinir. Geçersiz kılınan bir işleve yönelik bir çağrının Çalışma Zamanında çözüldüğü bu Mekanizmada.
public class DynamicBindingTest {
public static void main(String args[]) {
Vehicle vehicle = new Car(); //here Type is vehicle but object will be Car
vehicle.start(); //Car's start called because start() is overridden method
}
}
class Vehicle {
public void start() {
System.out.println("Inside start method of Vehicle");
}
}
class Car extends Vehicle {
@Override
public void start() {
System.out.println("Inside start method of Car");
}
}
Çıktı:
Arabanın içten çalıştırma yöntemi
Statik Bağlama / derleme zamanı polimorfizmi:
Hangi yöntemin çağrılacağına yalnızca derleme zamanında karar verilir.
public class StaticBindingTest {
public static void main(String args[]) {
Collection c = new HashSet();
StaticBindingTest et = new StaticBindingTest();
et.sort(c);
}
//overloaded method takes Collection argument
public Collection sort(Collection c){
System.out.println("Inside Collection sort method");
return c;
}
//another overloaded method which takes HashSet argument which is sub class
public Collection sort(HashSet hs){
System.out.println("Inside HashSet sort method");
return hs;
}
}
Çıktı: Koleksiyon içi sıralama yöntemi
yöntem aşırı yükleme , derleme zamanı / statik polimorfizm örneğidir, çünkü yöntem çağrısı ve yöntem tanımı arasındaki yöntem bağlama derleme zamanında gerçekleşir ve sınıfın referansına bağlıdır (derleme zamanında oluşturulan ve yığına giden referans).
yöntem geçersiz kılma , çalıştırma zamanı / dinamik polimorfizm örneğidir, çünkü yöntem çağrısı ve yöntem tanımı arasındaki yöntem bağlama çalışma zamanında gerçekleşir ve sınıfın nesnesine bağlıdır (çalışma zamanında oluşturulan ve yığına giden nesne).
Basit bir ifadeyle:
Statik polimorfizm : Aynı yöntem adı, aynı sınıftaki farklı türde veya sayıda parametrelerle(farklı imza) aşırı yüklenmiştir . Hedeflenen yöntem çağrısı derleme zamanında çözülür.
Dinamik polimorfizm : Aynı yöntem, farklı sınıflarda aynı imza ile geçersiz kılınır . Yöntemin çağrıldığı nesnenin türü derleme zamanında bilinmemektedir, ancak çalışma zamanında kararlaştırılacaktır.
Genellikle aşırı yükleme, polimorfizm olarak kabul edilmeyecektir.
Java eğitim sayfasından :
Bir sınıfın alt sınıfları, kendi benzersiz davranışlarını tanımlayabilir ve yine de üst sınıfın aynı işlevlerinden bazılarını paylaşabilir.
Generally overloading won't be considered as polymorphism.
lütfen bu noktayı detaylandırır mısınız?
Yöntem Aşırı Yüklemesi , Statik Polimorfizm olarak bilinir ve ayrıca Derleme Zamanı Polimorfizmi veya Statik Bağlama olarak da bilinir çünkü aşırı yüklenmiş yöntem çağrıları, bağımsız değişken listesi ve yöntemi çağırdığımız başvuru temelinde derleyici tarafından derleme zamanında çözülür.
Ve Yöntemi Geçersiz Kılma , Dinamik Polimorfizm veya basit Polimorfizm veya Çalışma Zamanı Yöntemi Gönderimi veya Dinamik Bağlama olarak bilinir çünkü geçersiz kılınan yöntem çağrısı çalışma zamanında çözülür.
Bunun neden böyle olduğunu anlamak için bir örnek Mammal
ve Human
sınıf alalım
class Mammal {
public void speak() { System.out.println("ohlllalalalalalaoaoaoa"); }
}
class Human extends Mammal {
@Override
public void speak() { System.out.println("Hello"); }
public void speak(String language) {
if (language.equals("Hindi")) System.out.println("Namaste");
else System.out.println("Hello");
}
}
Aşağıdaki kod satırlarına çıktı ve bayt kodu ekledim
Mammal anyMammal = new Mammal();
anyMammal.speak(); // Output - ohlllalalalalalaoaoaoa
// 10: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V
Mammal humanMammal = new Human();
humanMammal.speak(); // Output - Hello
// 23: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V
Human human = new Human();
human.speak(); // Output - Hello
// 36: invokevirtual #7 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:()V
human.speak("Hindi"); // Output - Namaste
// 42: invokevirtual #9 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:(Ljava/lang/String;)V
Yukarıdaki koda bakarak, humanMammal.speak (), human.speak () ve human.speak ("Hindi") bayt kodlarının tamamen farklı olduğunu görebiliriz çünkü derleyici, argüman listesine dayalı olarak aralarında ayrım yapabilir. ve sınıf referansı. İşte bu yüzden Metot Aşırı Yüklemesi Statik Polimorfizm olarak bilinir .
Ancak anyMammal.speak () ve humanMammal.speak () için bayt kodu aynıdır çünkü derleyiciye göre her iki yöntem de Mammal referansında çağrılır, ancak her iki yöntem çağrısı için çıktı farklıdır çünkü çalışma zamanında JVM bir referansın hangi nesneyi tuttuğunu bilir ve JVM çağırır nesnedeki yöntem ve bu nedenle Yöntemi Geçersiz Kılma Dinamik Polimorfizm olarak bilinir.
Dolayısıyla yukarıdaki kod ve bayt kodundan, derleme aşamasında çağırma yönteminin referans türünden ele alındığı açıktır. Ancak yürütme zamanında, referansın tuttuğu nesneden yöntem çağrılacaktır.
Bununla ilgili daha fazla bilgi edinmek istiyorsanız , JVM Yöntemi Aşırı Yüklemeyi ve Dahili Olarak Geçersiz Kılmayı Nasıl İşliyor hakkında daha fazla bilgi edinebilirsiniz .
Statik Polimorfizm: Hangi yöntemin gerçekleştirileceğini çözme kararının derleme süresi sırasında belirlendiği yerdir. Yöntem Aşırı Yüklemesi buna bir örnek olabilir.
Dinamik Çok Biçimlilik: hangi yöntemin yürütüleceğini seçme kararının çalışma zamanı sırasında belirlendiği yerdir. Yöntemi Geçersiz Kılma buna bir örnek olabilir.
Polimorfizm, bir nesnenin aynı tetikleyici için farklı davranma yeteneğini ifade eder.
Statik polimorfizm (Derleme zamanı Polimorfizmi)
Dinamik Polimorfizm (Çalışma Zamanı Polimorfizmi)
Derleme zamanı polimorfizmi (Static Binding / Early Binding): Statik polimorfizmde, kodumuzda bir yöntem çağırırsak, o yöntemin hangi tanımının gerçekten çağrılacağı yalnızca derleme zamanında çözülür.
(veya)
Derleme zamanında Java, yöntem imzalarını kontrol ederek hangi yöntemi çağıracağını bilir. Bu nedenle, buna derleme zamanı polimorfizmi veya statik bağlama denir.
Dinamik Çok Biçimlilik (Geç Bağlama / Çalışma Zamanı Çok Biçimliliği): Java, çalışma zamanında, hangi nesnenin gerçekte referans tarafından işaret edildiğini belirlemek için çalışma zamanına kadar bekler. Çalışma zamanı polimorfizmi olarak adlandırdığımız için, çalışma zamanında yöntem çözümlemesi alınmıştır.
Aşağıdaki kodu düşünün:
public class X
{
public void methodA() // Base class method
{
System.out.println ("hello, I'm methodA of class X");
}
}
public class Y extends X
{
public void methodA() // Derived Class method
{
System.out.println ("hello, I'm methodA of class Y");
}
}
public class Z
{
public static void main (String args []) {
//this takes input from the user during runtime
System.out.println("Enter x or y");
Scanner scanner = new Scanner(System.in);
String value= scanner.nextLine();
X obj1 = null;
if(value.equals("x"))
obj1 = new X(); // Reference and object X
else if(value.equals("y"))
obj2 = new Y(); // X reference but Y object
else
System.out.println("Invalid param value");
obj1.methodA();
}
}
Şimdi, koda bakarak methodA () 'nın hangi uygulamasının çalıştırılacağını asla söyleyemezsiniz, çünkü bu, kullanıcının çalışma zamanı sırasında verdiği değere bağlıdır. Bu nedenle, hangi yöntemin çağrılacağına yalnızca çalışma süresi sırasında karar verilir. Bu nedenle, Çalışma Zamanı polimorfizmi.
Yöntem aşırı yükleme bir derleme zamanı polimorfizmidir, kavramı anlamak için bir örnek alalım.
class Person //person.java file
{
public static void main ( String[] args )
{
Eat e = new Eat();
e.eat(noodle); //line 6
}
void eat (Noodles n) //Noodles is a object line 8
{
}
void eat ( Pizza p) //Pizza is a object
{
}
}
Bu örnekte Person, Pizza veya Erişte yiyebileceğini gösteren bir yeme yöntemine sahiptir. Bu Person.java'yı derlediğimizde eat yönteminin aşırı yüklendiğini, derleyici "e.eat (erişte) yöntem çağrısını [satır 6'da] 8. satırda belirtilen yöntem tanımıyla, yani erişteleri parametre olarak alan yöntemle çözer. ve tüm süreç Derleyici tarafından yapılır, yani Derleme zamanı Polimorfizmidir.Yöntem çağrısının yöntem tanımı ile değiştirilmesi işlemi bağlama olarak adlandırılır, bu durumda derleyici tarafından yapılır, bu nedenle erken bağlama olarak adlandırılır.
Naresh'in cevabını takiben, dinamik polimorfizm, sanal makinenin varlığı ve yerel olarak çalışan kod yerine çalışma zamanında kodu yorumlama yeteneği nedeniyle Java'da yalnızca "dinamik" tir.
C ++ 'da, eğer gcc kullanılarak yerel bir ikiliye derleniyorsa, derleme zamanında çözülmelidir, tabii ki; ancak, sanal tablodaki çalışma zamanı atlama ve thunk hala 'arama' veya 'dinamik' olarak anılır. C, B'yi miras alırsa ve siz beyan ederseniz B* b = new C(); b->method1();
, b, derleyici tarafından C içindeki bir B nesnesine işaret edecek şekilde çözümlenecektir (basit bir sınıf bir sınıf durumunu miras alır, C ve C içindeki B nesnesi aynı bellek adresinde başlayacaktır, dolayısıyla hiçbir şey yapılması gerekir; her ikisinin de kullandığı vptr'ye işaret edecektir). C, B ve A'yı miras alırsa, yöntem1 için C girişi içindeki A nesnesinin sanal işlev tablosu, işaretçiyi kapsülleyen C nesnesinin başlangıcına kaydıracak ve ardından gerçek A :: method1 () 'e iletecek bir thunk'a sahip olacaktır. C'nin geçersiz kıldığı metin bölümünde. İçinC* c = new C(); c->method1()
, c halihazırda dış C nesnesine işaret ediyor olacak ve işaretçi metin segmentindeki C :: method1 () 'e iletilecek. Bakınız: http://www.programmersought.com/article/2572545946/
Java'da, B b = new C(); b.method1();
sanal makine, b ile eşleştirilen nesnenin türünü dinamik olarak kontrol edebilir ve doğru işaretçiyi geçerek doğru yöntemi çağırabilir. Sanal makinenin ekstra adımı, derleme zamanında bilinebilse bile, sanal işlev tablolarına veya derleme zamanında çözülen türe olan ihtiyacı ortadan kaldırır. Bu, sanal bir makine söz konusu olduğunda ve kod yalnızca bayt koduna derlendiğinde mantıklı olan, bunu yapmanın farklı bir yoludur.