ความแตกต่างระหว่างความแตกต่างระหว่างไดนามิกและคงที่ใน Java คืออะไร?


118

ใครช่วยยกตัวอย่างง่ายๆที่อธิบายความแตกต่างระหว่างDynamicและStatic polymorphism ใน Java


4
การลบล้างบางครั้งเรียกว่า "ความแตกต่างแบบคงที่" สิ่งนี้ยืดออกไปเล็กน้อย แต่นั่นคือสิ่งที่เกิดขึ้น
dasblinkenlight

@dasblinkenlight ขอบคุณสำหรับข้อมูล มีตัวอย่างไหม ??
Prabhakar Manthena

ค้นหา "method overloading" และ "method overriding"
dasblinkenlight

5
ฉันไม่เข้าใจว่าการโอเวอร์โหลดเป็นความหลากหลายอย่างไร Polymorphism เป็นแนวคิดของวัตถุ เราควรจะสามารถแสดงวัตถุ B เป็นวัตถุ A. ได้จากด้านล่าง (คำตอบ) ตัวอย่างที่คุณแสดงให้สุนัขเป็นสัตว์และด้วยเหตุนี้จึงเป็นความหลากหลาย แต่ในการใช้งานมากเกินไปคุณจะเรียกวิธีการอื่น แต่ใช้ "ชื่อเดียวกัน" มันเป็นความหลากหลายได้อย่างไร ดังนั้น "การผูกแบบคงที่" จึงเป็นคำที่ถูกต้องในการใช้ แต่ความแตกต่างแบบคงที่ไม่ได้อยู่ในกรณีที่มีการใช้งานมากเกินไป
Punith Raj

@PunithRaj คุณอาจหมายถึงการย่อย polymorphism มีอีกประเภทหนึ่งที่เรียกว่าAd hocซึ่งใช้กับการบรรทุกเกินพิกัด
Kelvin

คำตอบ:


196

ความแตกต่าง

1. การผูกแบบคงที่ / การรวมเวลาการผูก / การผูกมัดในช่วงต้น / การโอเวอร์โหลดวิธีการ (ในคลาสเดียวกัน)

2. การผูกแบบไดนามิก / การผูกเวลารัน / การผูกล่าช้า / การแทนที่วิธีการ (ในคลาสที่แตกต่างกัน)

ตัวอย่างการโอเวอร์โหลด:

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
   }
}

6
ฉันยังใหม่กับ Java ดังนั้นแค่อยากรู้ว่าอะไรคือแนวคิดพื้นฐานระหว่างAnimal reference but Dog objectทำไมเราถึงใช้Dog reference and dog objectไม่ได้
pratyay

3
ในตัวอย่างข้างต้นฉันพยายามแสดงแนวคิดของความหลากหลาย เราสามารถสร้างการอ้างอิงและวัตถุของคลาสเดียวกัน แต่เราไม่สามารถบรรลุวิธีการแทนที่ โปรดอ่านโพสต์ด้านล่าง: stackoverflow.com/questions/12159601/…
KhAn SaAb

method overloading คือ Compile time polymorphism เป็นวิธีเดียวกัน constructor overloading ยัง Compile time polymorphism หรือไม่?
Gaali Prabhakar

29
  • วิธีการโอเวอร์โหลดจะเป็นตัวอย่างของความหลากหลายแบบคงที่

  • ในขณะที่การลบล้างจะเป็นตัวอย่างของความหลากหลายแบบไดนามิก

    เนื่องจากในกรณีที่มีการโอเวอร์โหลดในเวลาคอมไพล์คอมไพเลอร์จะรู้ว่าวิธีใดที่จะเชื่อมโยงกับการเรียกใช้ อย่างไรก็ตามมันถูกกำหนดที่รันไทม์สำหรับความหลากหลายแบบไดนามิก


17

ความหลากหลายแบบไดนามิก (เวลาทำงาน)คือความหลากหลายที่มีอยู่ในเวลาทำงาน ที่นี่คอมไพเลอร์ Java ไม่เข้าใจว่าเมธอดใดถูกเรียกในเวลาคอมไพล์ JVM เท่านั้นที่ตัดสินใจว่าจะเรียกเมธอดใดในขณะรันไทม์ การโอเวอร์โหลดเมธอดและการแทนที่เมธอดโดยใช้วิธีอินสแตนซ์เป็นตัวอย่างของความหลากหลายแบบไดนามิก

ตัวอย่างเช่น,

  • พิจารณาแอปพลิเคชันที่ทำให้เป็นอนุกรมและแยกลำดับของเอกสารประเภทต่างๆ

  • เราสามารถมี 'เอกสาร' เป็นคลาสพื้นฐานและคลาสประเภทเอกสารต่างๆที่ได้มาจากมัน เช่น XMLDocument, WordDocument เป็นต้น

  • คลาสเอกสารจะกำหนดเมธอด 'Serialize ()' และ 'De-serialize ()' เป็นเสมือนและคลาสที่ได้รับแต่ละคลาสจะใช้วิธีการเหล่านี้ในแบบของตัวเองตามเนื้อหาจริงของเอกสาร

  • เมื่อเอกสารประเภทต่างๆจำเป็นต้องทำให้เป็นซีเรียล / ไม่เป็นซีเรียลอ็อบเจ็กต์เอกสารจะถูกอ้างอิงโดยการอ้างอิงคลาส 'เอกสาร' (หรือตัวชี้) และเมื่อมีการเรียกเมธอด 'Serialize ()' หรือ 'De-serialize ()' ในนั้นจะมีการเรียกวิธีการเสมือนเวอร์ชันที่เหมาะสม

ความหลากหลายแบบคงที่ (เวลาคอมไพล์)คือความหลากหลายที่แสดงในเวลาคอมไพล์ ที่นี่คอมไพเลอร์ Java รู้ว่าวิธีใดเรียกว่า วิธีการโอเวอร์โหลดและวิธีการแทนที่โดยใช้วิธีคงที่ วิธีการแทนที่โดยใช้วิธีส่วนตัวหรือขั้นสุดท้ายเป็นตัวอย่างของความหลากหลายแบบคงที่

ตัวอย่างเช่น,

  • อ็อบเจ็กต์พนักงานอาจมีสองวิธีการพิมพ์ () วิธีหนึ่งโดยไม่มีข้อโต้แย้งและอีกวิธีหนึ่งใช้สตริงคำนำหน้าเพื่อแสดงพร้อมกับข้อมูลพนักงาน

  • ด้วยอินเทอร์เฟซเหล่านี้เมื่อเมธอด print () ถูกเรียกโดยไม่มีอาร์กิวเมนต์ใด ๆ คอมไพเลอร์เมื่อมองไปที่อาร์กิวเมนต์ของฟังก์ชันจะรู้ว่าฟังก์ชันใดถูกเรียกใช้และสร้างโค้ดอ็อบเจ็กต์ตามนั้น

สำหรับรายละเอียดเพิ่มเติมโปรดอ่าน "Polymorphism คืออะไร" (Google it)


2
คำตอบนี้เต็มไปด้วยข้อผิดพลาด: (1) วิธีการโอเวอร์โหลดไม่ใช่ความหลากหลายแบบไดนามิก มันเป็นความหลากหลายแบบคงที่ (2) วิธีการแบบคงที่จะไม่ถูกแทนที่พวกเขาจะถูกซ่อน / เงา (3) วิธีการส่วนตัวไม่ "ถูกลบล้าง" พวกเขาไม่เคยสืบทอดมาตั้งแต่แรก
John Red

15

การผูกหมายถึงการเชื่อมโยงระหว่างการเรียกใช้วิธีการและการกำหนดวิธีการ

ภาพนี้แสดงให้เห็นชัดเจนว่ามีผลผูกพันอะไร

ผูกพัน

ในภาพนี้การเรียก "a1.methodOne ()" มีผลผูกพันกับนิยาม methodOne () ที่สอดคล้องกันและการเรียก "a1.methodTwo ()" มีผลผูกพันกับนิยาม methodTwo () ที่เกี่ยวข้อง

สำหรับการเรียกทุกวิธีควรมีการกำหนดวิธีการที่เหมาะสม นี่เป็นกฎใน java หากคอมไพลเลอร์ไม่เห็นนิยามเมธอดที่เหมาะสมสำหรับการเรียกทุกเมธอดคอมไพเลอร์จะแสดงข้อผิดพลาด

ตอนนี้มาที่การรวมแบบคงที่และการผูกแบบไดนามิกใน java

การผูกแบบคงที่ใน Java:

การผูกแบบคงที่คือการผูกที่เกิดขึ้นระหว่างการคอมไพล์ เรียกอีกอย่างว่าการโยงก่อนเนื่องจากการผูกเกิดขึ้นก่อนที่โปรแกรมจะทำงานจริง

.

การผูกแบบคงที่สามารถแสดงได้ดังภาพด้านล่าง

ใส่คำอธิบายภาพที่นี่

ในภาพนี้ 'a1' เป็นตัวแปรอ้างอิงประเภทคลาส A ที่ชี้ไปยังออบเจ็กต์ของคลาส A 'a2' ยังเป็นตัวแปรอ้างอิงของคลาส A แต่ชี้ไปที่ออบเจ็กต์ของคลาส B

ในระหว่างการคอมไพล์ในขณะที่โยงคอมไพลเลอร์จะไม่ตรวจสอบชนิดของอ็อบเจ็กต์ที่ตัวแปรอ้างอิงเฉพาะชี้ไป เพียงแค่ตรวจสอบชนิดของตัวแปรอ้างอิงที่เรียกใช้เมธอดและตรวจสอบว่ามีนิยามวิธีการสำหรับมันในประเภทนั้นหรือไม่

ตัวอย่างเช่นสำหรับการเรียกเมธอด“ a1.method ()” ในภาพด้านบนคอมไพเลอร์จะตรวจสอบว่ามีการกำหนดวิธีการสำหรับ method () ในคลาส A หรือไม่เนื่องจาก 'a1′ เป็นประเภทคลาส A ในทำนองเดียวกันสำหรับการเรียกเมธอด“ a2.method ()” จะตรวจสอบว่ามีนิยามวิธีการสำหรับ method () ในคลาส A หรือไม่เนื่องจาก 'a2′ เป็นประเภทคลาส A ด้วย ไม่ได้ตรวจสอบว่าวัตถุใดชี้ 'a1' และ 'a2' การผูกแบบนี้เรียกว่าการผูกแบบคงที่

การผูกแบบไดนามิกใน Java:

การเชื่อมโยงแบบไดนามิกคือการเชื่อมโยงที่เกิดขึ้นระหว่างเวลาทำงาน เรียกอีกอย่างว่าการโยงสายเนื่องจากการผูกจะเกิดขึ้นเมื่อโปรแกรมกำลังทำงานจริง

ในระหว่างรันไทม์อ็อบเจ็กต์จริงถูกใช้สำหรับการโยง ตัวอย่างเช่นสำหรับการเรียก“ a1.method ()” ในภาพด้านบนจะมีการเรียก method () ของวัตถุจริงที่ชี้ไปที่ 'a1' สำหรับการเรียก“ a2.method ()” จะมีการเรียก method () ของวัตถุจริงที่ชี้ไปที่ 'a2' การผูกแบบนี้เรียกว่าการผูกแบบไดนามิก

การเชื่อมโยงแบบไดนามิกของตัวอย่างข้างต้นสามารถแสดงได้ดังต่อไปนี้

ใส่คำอธิบายภาพที่นี่

อ้างอิงstatic-binding-and-dynamic-binding-in-java


ดีขึ้นกว่าก่อน.
AnBisw

8

Polymorphism: ความ หลากหลายเป็นความสามารถของวัตถุในหลายรูปแบบ การใช้ความหลากหลายของความหลากหลายใน OOP เกิดขึ้นเมื่อการอ้างอิงคลาสพาเรนต์ถูกใช้เพื่ออ้างถึงอ็อบเจ็กต์คลาสลูก

Dynamic Binding / Runtime Polymorphism:

เวลาเรียกใช้ Polymorphism หรือที่เรียกว่า method overriding ในกลไกนี้ซึ่งการเรียกไปยังฟังก์ชันที่ถูกแทนที่จะได้รับการแก้ไขในเวลาทำงาน

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");
    }
}

เอาท์พุท:

วิธีสตาร์ทภายในรถ

ความหลากหลายของการผูกแบบคงที่ / เวลาคอมไพล์:

วิธีการที่จะเรียกนั้นจะตัดสินใจในเวลาคอมไพล์เท่านั้น

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;
    }

}

เอาท์พุท: Inside Collection sort


8

method overloadingเป็นตัวอย่างของ compile time / static polymorphism เนื่องจากวิธีการผูกระหว่าง method call และ method definition เกิดขึ้นที่ compile time และขึ้นอยู่กับ reference ของ class (การอ้างอิงที่สร้างใน compile time และไปที่ stack)

method overridingเป็นตัวอย่างของ run time / dynamic polymorphism เนื่องจากวิธีการผูกระหว่าง method call และ method definition เกิดขึ้นที่ run time และขึ้นอยู่กับ object ของ class (object ที่สร้างขึ้นที่ runtime และไปที่ heap)


* (object create at run time และไปที่ heap) ควรรันเวลา
พบกัน

7

พูดง่ายๆคือ

ความแตกต่างแบบคงที่ : ชื่อเมธอดเดียวกันมีมากเกินไปโดยมีประเภทหรือจำนวนพารามิเตอร์ที่แตกต่างกันในคลาสเดียวกัน (ลายเซ็นต่างกัน) การเรียกเมธอดเป้าหมายได้รับการแก้ไขในเวลาคอมไพล์

ความหลากหลายแบบไดนามิก : เมธอดเดียวกันถูกแทนที่ด้วยลายเซ็นเดียวกันในคลาสต่างๆ ไม่ทราบชนิดของอ็อบเจ็กต์ที่จะเรียกใช้เมธอดในขณะคอมไพล์ แต่จะถูกกำหนดในขณะรันไทม์

โดยทั่วไปแล้วการโอเวอร์โหลดจะไม่ถูกพิจารณาว่าเป็นความหลากหลาย

จากหน้าสอน Java :

คลาสย่อยของคลาสสามารถกำหนดพฤติกรรมเฉพาะของตนเองและยังแชร์ฟังก์ชันการทำงานบางอย่างของคลาสพาเรนต์ได้


Generally overloading won't be considered as polymorphism.คุณช่วยอธิบายอย่างละเอียดในประเด็นนี้ได้ไหม
นายก

1
การผูกและการลบล้างแบบไดนามิกเป็นจุดที่โดดเด่นสำหรับความหลากหลาย
Ravindra babu

5

Method Overloadingเรียกว่าStatic Polymorphismและเรียกอีกอย่างว่าCompile Time PolymorphismหรือStatic Bindingเนื่องจากการเรียกเมธอดที่โอเวอร์โหลดจะได้รับการแก้ไขในเวลาคอมไพล์โดยคอมไพเลอร์บนพื้นฐานของรายการอาร์กิวเมนต์และการอ้างอิงที่เราเรียกใช้เมธอด

และMethod Overridingเรียกว่าDynamic PolymorphismหรือPolymorphismหรือRuntime Method DispatchหรือDynamic Bindingเนื่องจากการเรียกเมธอดที่ถูกแทนที่ได้รับการแก้ไขที่รันไทม์

เพื่อให้เข้าใจว่าเหตุใดจึงเป็นเช่นนั้นเรามาดูตัวอย่างMammalและHumanชั้นเรียน

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");
    }

}

ฉันได้รวมเอาท์พุทและรหัส bytecode ไว้ในบรรทัดด้านล่างของโค้ด

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

และจากการดูโค้ดด้านบนเราจะเห็นว่า bytecodes ของ humanMammal.speak (), human.speak () และ human.speak ("ภาษาฮินดี") นั้นแตกต่างกันโดยสิ้นเชิงเนื่องจากคอมไพเลอร์สามารถแยกความแตกต่างระหว่างสิ่งเหล่านี้ตามรายการอาร์กิวเมนต์ และการอ้างอิงชั้นเรียน และนี่คือเหตุผลวิธีมากไปเป็นที่รู้จักกันคงความแตกต่าง

แต่ bytecode สำหรับ anyMammal.speak () และ humanMammal.speak () เหมือนกันเพราะตามคอมไพเลอร์ทั้งสองวิธีถูกเรียกด้วยการอ้างอิงสัตว์เลี้ยงลูกด้วยนม แต่เอาต์พุตสำหรับการเรียกเมธอดทั้งสองแตกต่างกันเนื่องจากที่รันไทม์ JVM รู้ว่าวัตถุใดที่การอ้างอิงถืออยู่และการเรียก JVM เมธอดบนวัตถุและนี่คือสาเหตุที่ Method Overriding เรียกว่า Dynamic Polymorphism

ดังนั้นจากโค้ดด้านบนและ bytecode เป็นที่ชัดเจนว่าในระหว่างวิธีการเรียกเฟสคอมไพล์จะพิจารณาจากประเภทการอ้างอิง แต่เมธอดในเวลาดำเนินการจะถูกเรียกใช้จากอ็อบเจ็กต์ที่มีการอ้างอิงอยู่

หากคุณต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้คุณสามารถอ่านเพิ่มเติมเกี่ยวกับวิธีการวิธีการที่ไม่ JVM จับมากไปและแทนที่ภายใน


3

Static Polymorphism: เป็นการตัดสินใจที่จะแก้ไขวิธีการที่จะทำให้สำเร็จนั้นจะถูกกำหนดในช่วงเวลาคอมไพล์ วิธีการโอเวอร์โหลดอาจเป็นตัวอย่างของสิ่งนี้

Dynamic Polymorphism: เป็นการตัดสินใจที่จะเลือกวิธีการที่จะดำเนินการโดยกำหนดไว้ในระหว่างรันไทม์ Method Overriding อาจเป็นตัวอย่างของสิ่งนี้


3

ความหลากหลายหมายถึงความสามารถของวัตถุในการทำงานที่แตกต่างกันสำหรับทริกเกอร์เดียวกัน

ความหลากหลายแบบคงที่ (Polymorphism เวลาคอมไพล์)

  • Static Polymorphism เป็นตัวกำหนดว่าจะดำเนินการด้วยวิธีใดในช่วงเวลาคอมไพล์
  • Method Overloading เป็นตัวอย่างของความหลากหลายแบบคงที่และจำเป็นต้องเกิดความหลากหลายแบบคงที่
  • Static Polymorphism ทำได้โดยการจับแบบคงที่
  • Static Polymorphism เกิดขึ้นในคลาสเดียวกัน
  • ไม่จำเป็นต้องมีการกำหนดอ็อบเจ็กต์สำหรับความหลากหลายแบบคงที่
  • การถ่ายทอดทางพันธุกรรมไม่เกี่ยวข้องกับความหลากหลายแบบคงที่

ความแตกต่างแบบไดนามิก (Runtime Polymorphism)

  • Dynamic Polymorphism เป็นตัวกำหนดว่าจะใช้วิธีใดในรันไทม์
  • Method Overriding เป็นตัวอย่างของความหลากหลายแบบไดนามิกและจำเป็นต้องเกิดความแตกต่างแบบไดนามิก
  • Dynamic Polymorphism ทำได้โดยการผูกแบบไดนามิก
  • Dynamic Polymorphism เกิดขึ้นระหว่างคลาสต่างๆ
  • จำเป็นต้องมีเมื่อวัตถุคลาสย่อยถูกกำหนดให้กับออบเจ็กต์ระดับสูงสำหรับความหลากหลายแบบไดนามิก
  • การถ่ายทอดทางพันธุกรรมเกี่ยวข้องกับความหลากหลายแบบไดนามิก

1

ความหลากหลายของเวลาคอมไพล์ (Static Binding / Early Binding):ในความหลากหลายแบบคงที่ถ้าเราเรียกเมธอดในโค้ดของเราคำจำกัดความของเมธอดนั้นจะถูกเรียกใช้จริงในเวลาคอมไพล์เท่านั้น

(หรือ)

ในขณะคอมไพล์ Java จะรู้ว่าจะเรียกใช้เมธอดใดโดยตรวจสอบลายเซ็นของเมธอด ดังนั้นสิ่งนี้เรียกว่าความหลากหลายของเวลาคอมไพล์หรือการเชื่อมแบบคงที่

Dynamic Polymorphism (Late Binding / Runtime Polymorphism):ในขณะรัน Java จะรอจนกว่ารันไทม์เพื่อตรวจสอบว่าวัตถุใดถูกชี้โดยการอ้างอิง ความละเอียดของเมธอดถูกนำมาใช้ที่รันไทม์เนื่องจากเราเรียกว่าความหลากหลายของเวลาทำงาน


1

พิจารณารหัสด้านล่าง:

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();
}
}

ตอนนี้การดูโค้ดคุณไม่สามารถบอกได้ว่าจะใช้ methodA () ใดเนื่องจากขึ้นอยู่กับค่าที่ผู้ใช้ให้ระหว่างรันไทม์ ดังนั้นจึงมีการตัดสินใจระหว่างรันไทม์เท่านั้นว่าจะเรียกใช้วิธีใด ดังนั้นความหลากหลายของรันไทม์


0

วิธีการโอเวอร์โหลดเป็นความหลากหลายของเวลาคอมไพล์ลองมาเป็นตัวอย่างเพื่อทำความเข้าใจแนวคิด

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
  {

  }

}

ในตัวอย่างนี้บุคคลมีวิธีการกินที่แสดงว่าเขาสามารถกินพิซซ่าหรือบะหมี่ได้ ว่าเมธอด eat นั้นโอเวอร์โหลดเมื่อเราคอมไพล์ Person.java คอมไพเลอร์แก้ไขเมธอดที่เรียกว่า "e.eat (noodles) [ซึ่งอยู่ที่บรรทัดที่ 6] ด้วยนิยามวิธีการที่ระบุไว้ในบรรทัดที่ 8 นั่นคือเมธอดที่ใช้เส้นก๋วยเตี๋ยวเป็นพารามิเตอร์ และกระบวนการทั้งหมดจะทำโดยคอมไพเลอร์ดังนั้นจึงเป็น Compile time Polymorphism กระบวนการแทนที่การเรียกเมธอดด้วยนิยามเมธอดเรียกว่าการผูกในกรณีนี้คอมไพเลอร์จะทำโดยคอมไพเลอร์จึงเรียกว่าการรวมครั้งแรก


0

จากคำตอบของ Naresh ความหลากหลายแบบไดนามิกเป็นเพียง 'ไดนามิก' ใน Java เนื่องจากการมีอยู่ของเครื่องเสมือนและความสามารถในการตีความรหัสในขณะทำงานแทนที่จะเป็นรหัสที่ทำงานโดยกำเนิด

ใน C ++ จะต้องได้รับการแก้ไขในเวลาคอมไพล์หากมีการคอมไพล์เป็นไบนารีดั้งเดิมโดยใช้ gcc อย่างไรก็ตาม runtime jump และ thunk ในตารางเสมือนยังคงเรียกว่า 'lookup' หรือ 'dynamic' ถ้า C สืบทอด B และคุณประกาศB* b = new C(); b->method1();b จะได้รับการแก้ไขโดยคอมไพเลอร์ให้ชี้ไปที่วัตถุ B ภายใน C (สำหรับคลาสธรรมดาจะสืบทอดสถานการณ์คลาสวัตถุ B ภายใน C และ C จะเริ่มต้นที่ที่อยู่หน่วยความจำเดียวกันดังนั้นจึงไม่มีอะไร จะต้องทำมันจะชี้ไปที่ vptr ที่ทั้งคู่ใช้) ถ้า C สืบทอด B และ A ตารางฟังก์ชันเสมือนของวัตถุ A ภายในรายการ C สำหรับ method1 จะมีขีด จำกัด ซึ่งจะหักล้างตัวชี้ไปที่จุดเริ่มต้นของวัตถุ C ที่ห่อหุ้มแล้วส่งผ่านไปยัง A :: method1 () จริง ในส่วนข้อความที่ C ได้ลบล้าง สำหรับC* c = new C(); c->method1()c จะชี้ไปที่วัตถุ C ด้านนอกอยู่แล้วและตัวชี้จะถูกส่งไปยัง C :: method1 () ในส่วนข้อความ อ้างถึง: http://www.programmersought.com/article/2572545946/

ใน java สำหรับB b = new C(); b.method1();เครื่องเสมือนสามารถตรวจสอบประเภทของวัตถุที่จับคู่กับ b แบบไดนามิกและสามารถส่งผ่านตัวชี้ที่ถูกต้องและเรียกวิธีการที่ถูกต้อง ขั้นตอนพิเศษของเครื่องเสมือนช่วยลดความจำเป็นในการใช้ตารางฟังก์ชันเสมือนหรือประเภทที่ได้รับการแก้ไขในเวลาคอมไพล์แม้ว่าจะสามารถทราบได้ในเวลาคอมไพล์ก็ตาม เป็นเพียงวิธีการอื่นในการทำซึ่งเหมาะสมเมื่อมีส่วนเกี่ยวข้องกับเครื่องเสมือนและโค้ดจะถูกคอมไพล์เป็น bytecode

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.