Adakah yang bisa memberikan contoh sederhana yang menjelaskan perbedaan antara Polimorfisme Dinamis dan Statis di Jawa?
Adakah yang bisa memberikan contoh sederhana yang menjelaskan perbedaan antara Polimorfisme Dinamis dan Statis di Jawa?
Jawaban:
Polimorfisme
1. Penjilidan Statis / Pengikatan Waktu Kompilasi / Pengikatan awal / Overloading metode. (Di kelas yang sama)
2. Pengikatan dinamis / Pengikatan Run-Time / Pengikatan akhir / Penggantian metode. (Dalam kelas yang berbeda)
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
, mengapa kita tidak bisa menggunakan Dog reference and dog object
?
Metode overloading akan menjadi contoh polimorfisme statis
sedangkan menimpa akan menjadi contoh polimorfisme dinamis.
Karena, jika terjadi kelebihan beban, pada waktu kompilasi kompilator mengetahui metode mana yang akan ditautkan ke panggilan tersebut. Namun, ditentukan saat runtime untuk polimorfisme dinamis
Polimorfisme dinamis (run time) adalah polimorfisme yang ada pada saat run-time. Di sini, kompilator Java tidak memahami metode mana yang dipanggil pada waktu kompilasi. Hanya JVM yang memutuskan metode mana yang dipanggil pada saat run-time. Overloading metode dan penggantian metode menggunakan metode instance adalah contoh polimorfisme dinamis.
Sebagai contoh,
Pertimbangkan aplikasi yang membuat serialisasi dan de-serialisasi berbagai jenis dokumen.
Kita dapat memiliki 'Document' sebagai kelas dasar dan kelas tipe dokumen yang berbeda yang diturunkan darinya. Misalnya XMLDocument, WordDocument, dll.
Kelas dokumen akan mendefinisikan metode 'Serialize ()' dan 'De-serialize ()' sebagai virtual dan setiap kelas turunan akan mengimplementasikan metode ini dengan caranya sendiri berdasarkan konten sebenarnya dari dokumen.
Ketika jenis dokumen yang berbeda perlu diserialkan / dideserialisasikan, objek dokumen akan dirujuk oleh referensi kelas 'Dokumen' (atau penunjuk) dan ketika metode 'Serialize ()' atau 'De-serialize ()' dipanggil di atasnya, versi yang sesuai dari metode virtual dipanggil.
Polimorfisme statis (waktu kompilasi) adalah polimorfisme yang ditunjukkan pada waktu kompilasi. Di sini, compiler Java mengetahui metode mana yang dipanggil. Overloading metode dan penggantian metode menggunakan metode statis; overriding metode menggunakan metode pribadi atau final adalah contoh polimorfisme statis
Sebagai contoh,
Objek karyawan mungkin memiliki dua metode print (), satu tanpa argumen dan satu lagi mengambil string awalan untuk ditampilkan bersama dengan data karyawan.
Dengan adanya antarmuka ini, ketika metode print () dipanggil tanpa argumen apa pun, kompilator, yang melihat argumen fungsi, mengetahui fungsi mana yang akan dipanggil dan menghasilkan kode objek yang sesuai.
Untuk lebih jelasnya silahkan baca "Apa itu Polimorfisme" (Google it).
Binding mengacu pada hubungan antara pemanggilan metode dan definisi metode.
Gambar ini dengan jelas menunjukkan apa yang mengikat.
Dalam gambar ini, panggilan "a1.methodOne ()" mengikat ke definisi methodOne () terkait dan panggilan "a1.methodTwo ()" mengikat ke definisi methodTwo () yang sesuai.
Untuk setiap pemanggilan metode harus ada definisi metode yang tepat. Ini adalah aturan di java. Jika compiler tidak melihat definisi metode yang tepat untuk setiap panggilan metode, itu akan memunculkan kesalahan.
Sekarang, sampai pada pengikatan statis dan pengikatan dinamis di java.
Binding Statis Di Jawa:
Penjilidan statis adalah penjilidan yang terjadi selama kompilasi. Ini juga disebut pengikatan awal karena pengikatan terjadi sebelum program benar-benar dijalankan
.
Penjilidan statis dapat ditunjukkan seperti pada gambar di bawah ini.
Pada gambar ini, 'a1' adalah variabel referensi tipe kelas A yang menunjuk ke objek kelas A. 'a2' juga merupakan variabel referensi kelas A tetapi menunjuk ke objek kelas B.
Selama kompilasi, saat mengikat, kompilator tidak memeriksa jenis objek yang diarahkan oleh variabel referensi tertentu. Ini hanya memeriksa jenis variabel referensi yang melaluinya suatu metode dipanggil dan memeriksa apakah ada definisi metode untuk itu dalam jenis itu.
Sebagai contoh, untuk pemanggilan metode “a1.method ()” pada gambar di atas, compiler memeriksa apakah ada definisi metode untuk metode () di Kelas A. Karena 'a1 ′ adalah tipe Kelas A. Demikian pula, untuk pemanggilan metode "a2.method ()", ia memeriksa apakah ada definisi metode untuk metode () di Kelas A. Karena 'a2 ′ juga merupakan tipe Kelas A. Itu tidak memeriksa objek mana, 'a1' dan 'a2' yang menunjuk. Jenis pengikatan ini disebut pengikatan statis.
Pengikatan Dinamis Di Java:
Pengikatan dinamis adalah pengikatan yang terjadi selama waktu proses. Ini juga disebut pengikatan terlambat karena pengikatan terjadi ketika program benar-benar berjalan.
Selama waktu proses, objek aktual digunakan untuk penjilidan. Misalnya, untuk pemanggilan "a1.method ()" pada gambar di atas, metode () dari objek aktual yang ditunjuk oleh 'a1' akan dipanggil. Untuk panggilan "a2.method ()", metode () dari objek aktual yang ditunjuk oleh 'a2' akan dipanggil. Jenis pengikatan ini disebut pengikatan dinamis.
Pengikatan dinamis dari contoh di atas dapat ditunjukkan seperti di bawah ini.
Polimorfisme: Polimorfisme adalah kemampuan suatu objek untuk mengambil berbagai bentuk. Penggunaan polimorfisme yang paling umum di OOP terjadi ketika referensi kelas induk digunakan untuk merujuk ke objek kelas anak.
Dynamic Binding / Runtime Polymorphism:
Run time Polymorphism juga dikenal sebagai metode overriding. Dalam Mekanisme ini, panggilan ke fungsi yang diganti diselesaikan pada Waktu Proses.
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");
}
}
Keluaran:
Metode Inside Start Mobil
Pengikatan Statis / polimorfisme waktu kompilasi:
Metode mana yang akan dipanggil ditentukan hanya pada waktu kompilasi.
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;
}
}
Output: Di dalam Collection sort metho
method overloading adalah contoh waktu kompilasi / polimorfisme statis karena pengikatan metode antara pemanggilan metode dan definisi metode terjadi pada waktu kompilasi dan bergantung pada referensi kelas (referensi dibuat pada waktu kompilasi dan masuk ke stack).
method overriding adalah contoh run time / polimorfisme dinamis karena pengikatan metode antara pemanggilan metode dan definisi metode terjadi pada waktu proses dan bergantung pada objek kelas (objek yang dibuat saat runtime dan masuk ke heap).
Secara sederhana:
Polimorfisme statis : Nama metode yang sama dibebani dengan jenis atau jumlah parameter yang berbeda di kelas yang sama (tanda tangan berbeda). Panggilan metode yang ditargetkan diselesaikan pada waktu kompilasi.
Polimorfisme dinamis : Metode yang sama diganti dengan tanda tangan yang sama di kelas yang berbeda . Jenis objek tempat metode dipanggil tidak diketahui pada waktu kompilasi tetapi akan diputuskan pada waktu proses.
Umumnya kelebihan muatan tidak akan dianggap sebagai polimorfisme.
Dari halaman tutorial java :
Subclass dari suatu kelas dapat menentukan perilaku uniknya sendiri dan berbagi beberapa fungsionalitas yang sama dari kelas induk
Generally overloading won't be considered as polymorphism.
bisakah Anda menguraikan hal ini.
Metode Overloading dikenal sebagai Polimorfisme Statis dan juga Dikenal sebagai Polimorfisme Waktu Kompilasi atau Binding Statis karena pemanggilan metode yang kelebihan beban diselesaikan pada waktu kompilasi oleh kompilator berdasarkan daftar argumen dan referensi yang kami panggil metode tersebut.
Dan Method Overriding dikenal sebagai Dynamic Polymorphism atau simple Polymorphism atau Runtime Method Dispatch atau Dynamic Binding karena pemanggilan metode yang diganti diselesaikan pada saat runtime.
Untuk memahami mengapa ini terjadi, mari kita ambil contoh Mammal
dan Human
kelas
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");
}
}
Saya telah menyertakan output serta bytecode di baris kode di bawah ini
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
Dan dengan melihat kode di atas kita dapat melihat bahwa bytecode dari humanMammal.speak (), human.speak () dan human.speak ("Hindi") sama sekali berbeda karena kompilator dapat membedakannya berdasarkan daftar argumen dan referensi kelas. Dan inilah mengapa Metode Overloading dikenal sebagai Polimorfisme Statis .
Tetapi bytecode untuk anyMammal.speak () dan humanMammal.speak () sama karena menurut kompiler, kedua metode dipanggil pada referensi Mamalia tetapi keluaran untuk kedua panggilan metode berbeda karena pada waktu proses JVM mengetahui objek apa yang dipegang referensi dan panggilan JVM metode pada objek dan inilah mengapa Metode Menimpa dikenal sebagai Polimorfisme Dinamis.
Jadi dari kode dan bytecode di atas, jelas bahwa selama fase kompilasi metode pemanggilan dipertimbangkan dari tipe referensi. Tetapi pada saat eksekusi metode akan dipanggil dari objek yang dipegang referensi.
Jika Anda ingin tahu lebih banyak tentang ini, Anda dapat membaca lebih lanjut tentang Bagaimana JVM Menangani Metode Overloading dan Overriding Secara Internal .
Polimorfisme Statis: di mana keputusan untuk menyelesaikan metode mana yang akan dicapai, ditentukan selama waktu kompilasi. Metode Overloading bisa menjadi contoh ini.
Polimorfisme Dinamis: di mana keputusan untuk memilih metode mana yang akan dieksekusi, ditetapkan selama run-time. Metode Overriding bisa menjadi contoh ini.
Polimorfisme mengacu pada kemampuan suatu objek untuk berperilaku berbeda untuk pemicu yang sama.
Polimorfisme statis (Polimorfisme Waktu Kompilasi)
Polimorfisme Dinamis (Runtime Polymorphism)
Polimorfisme waktu kompilasi (Binding Statis / Binding Awal): Dalam polimorfisme statis, jika kita memanggil metode dalam kode kita, maka definisi metode mana yang akan dipanggil sebenarnya diselesaikan hanya pada waktu kompilasi.
(atau)
Pada waktu kompilasi, Java mengetahui metode mana yang akan dipanggil dengan memeriksa tanda tangan metode. Jadi, ini disebut polimorfisme waktu kompilasi atau pengikatan statis.
Polimorfisme Dinamis (Late Binding / Runtime Polymorphism): Pada waktu proses, Java menunggu hingga runtime untuk menentukan objek mana yang sebenarnya sedang diarahkan oleh referensi. Resolusi metode diambil pada waktu proses, karena itu kami menyebutnya sebagai polimorfisme waktu proses.
Perhatikan kode di bawah ini:
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();
}
}
Sekarang, melihat kode Anda tidak akan pernah tahu implementasi mana dari methodA () yang akan dieksekusi, Karena itu tergantung pada nilai apa yang diberikan pengguna selama runtime. Jadi, hanya diputuskan selama waktu proses untuk metode mana yang akan dipanggil. Oleh karena itu, polimorfisme runtime.
Metode overloading adalah polimorfisme waktu kompilasi, mari kita ambil contoh untuk memahami konsepnya.
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
{
}
}
Dalam contoh ini, Orang memiliki metode makan yang menyatakan bahwa dia dapat makan Pizza atau Mie. Bahwa metode makan kelebihan beban ketika kita mengkompilasi Person.java kompiler menyelesaikan panggilan metode "e.eat (noodles) [yang ada di baris 6] dengan definisi metode yang ditentukan di baris 8 yaitu metode itu yang mengambil noodles sebagai parameter dan seluruh proses dilakukan oleh Compiler sehingga disebut sebagai Compile time Polymorphism Proses penggantian pemanggilan metode dengan definisi metode disebut binding, dalam hal ini dilakukan oleh compiler sehingga disebut sebagai early binding.
Melanjutkan dari jawaban Naresh, polimorfisme dinamis hanya 'dinamis' di Java karena adanya mesin virtual dan kemampuannya untuk menafsirkan kode pada waktu proses daripada kode yang berjalan secara asli.
Dalam C ++ itu harus diselesaikan pada waktu kompilasi jika ia sedang dikompilasi ke biner asli menggunakan gcc, jelas; Namun, runtime jump dan thunk dalam tabel virtual masih disebut sebagai 'pencarian' atau 'dinamis'. Jika C mewarisi B, dan Anda mendeklarasikan B* b = new C(); b->method1();
, b akan diselesaikan oleh compiler untuk menunjuk ke objek B di dalam C (untuk kelas sederhana mewarisi situasi kelas, objek B di dalam C dan C akan mulai di alamat memori yang sama jadi tidak ada harus dilakukan; itu akan menunjuk ke vptr yang mereka berdua gunakan). Jika C mewarisi B dan A, tabel fungsi virtual dari objek A di dalam entri C untuk metode1 akan memiliki thunk yang akan mengimbangi penunjuk ke awal objek C enkapsulasi dan kemudian meneruskannya ke A :: method1 () yang sebenarnya di segmen teks yang telah diganti oleh C. UntukC* c = new C(); c->method1()
, c akan menunjuk ke objek C terluar dan penunjuk akan diteruskan ke C :: method1 () di segmen teks. Lihat: http://www.programmersought.com/article/2572545946/
Di java, untuk B b = new C(); b.method1();
, mesin virtual dapat secara dinamis memeriksa jenis objek yang dipasangkan dengan b dan dapat meneruskan penunjuk yang benar dan memanggil metode yang benar. Langkah ekstra dari mesin virtual menghilangkan kebutuhan akan tabel fungsi virtual atau jenis yang diselesaikan pada waktu kompilasi, bahkan ketika itu dapat diketahui pada waktu kompilasi. Ini hanya cara berbeda untuk melakukannya yang masuk akal ketika mesin virtual terlibat dan kode hanya dikompilasi ke bytecode.