ความแตกต่างใน Java (แบบคงที่และแบบไดนามิก)

⚡ สรุปอย่างชาญฉลาด

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

  • 🎭 มีหลายรูปแบบ แต่มีชื่อเดียวกัน: ความแตกต่างใน Java อนุญาตให้เมธอดชื่อเดียวกันส่งต่อไปยังการใช้งานที่แตกต่างกัน โดยขึ้นอยู่กับประเภทของอ็อบเจ็กต์จริงในขณะที่ดำเนินการ
  • 🔀 สองรสชาติ: โพลีมอร์ฟิซึมในขั้นตอนการคอมไพล์ใช้การโอเวอร์โหลดเมธอด ในขณะที่โพลีมอร์ฟิซึมในขั้นตอนการรันไทม์ใช้การโอเวอร์ไรด์เมธอดผ่านการสืบทอดและ JVM
  • ⛓️ การผูกข้อมูลแบบคงที่เทียบกับการผูกข้อมูลแบบไดนามิก: การเรียกใช้ฟังก์ชันแบบโอเวอร์โหลดจะได้รับการแก้ไขในระหว่างการคอมไพล์ผ่านการผูกแบบคงที่ ในขณะที่การเรียกใช้ฟังก์ชันแบบโอเวอร์ไรด์จะได้รับการแก้ไขในระหว่างการทำงานผ่านการผูกแบบไดนามิก
  • พลังของคีย์เวิร์ดขั้นสุดยอด: คีย์เวิร์ด `super` ช่วยให้คลาสย่อยสามารถเรียกใช้งานการทำงานของคลาสแม่ก่อนที่จะเพิ่มพฤติกรรมเฉพาะของตนเองเข้าไป
  • 🧪 การเข้าถึงในโลกแห่งความเป็นจริง: บัญชีธนาคาร ลำดับชั้นของเจ้าหน้าที่โรงพยาบาล และเครื่องมือแสดงผลรูปทรง ล้วนอาศัยหลักการโพลีมอร์ฟิซึมเพื่อรองรับความต้องการใหม่ๆ โดยไม่ทำให้โค้ดที่ผ่านการทดสอบแล้วเสียหาย

ความแตกต่างใน Java

Polymorphism คืออะไร Java?

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

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

คลิก Good Farm Animal Welfare Awards หากไม่สามารถเข้าถึงวิดีโอได้

เหตุใดจึงใช้โพลีมอร์ฟิซึมใน Java?

ความแตกต่างใน Java รูปแบบนี้ถูกนำมาใช้เพราะทำให้โค้ดมีความยืดหยุ่น นำกลับมาใช้ใหม่ได้ และบำรุงรักษาง่ายขึ้น ตัวแปรอ้างอิงตัวเดียวของคลาสแม่สามารถชี้ไปยังอ็อบเจ็กต์ลูกได้หลายตัว ดังนั้นการเรียกใช้แบบเดียวกันจึงปรับให้เข้ากับคลาสย่อยใดก็ตามที่ถูกส่งเข้ามา รูปแบบนี้ช่วยให้โค้ดที่ผ่านการทดสอบแล้วไม่เปลี่ยนแปลง ในขณะที่พฤติกรรมใหม่ถูกเพิ่มเข้ามาผ่านคลาสย่อยเฉพาะ ซึ่งเป็นเหตุผลว่าทำไมเฟรมเวิร์กอย่าง Spring และ Jakarta EE จึงใช้รูปแบบนี้

Java ความแตกต่างใน OOP พร้อมตัวอย่าง

พิจารณาคลาสแม่คลาสหนึ่งชื่อ... ลงชื่อเข้าใช้ โดยมีฟังก์ชันสำหรับการฝากและถอนเงิน คลาส Account มีคลาสย่อยสองคลาส การดำเนินการฝากและถอนเงินนั้นเหมือนกันสำหรับบัญชีออมทรัพย์และบัญชีกระแสรายวัน ดังนั้นเมธอดที่สืบทอดมาจากคลาส Account จึงใช้งานได้

มรดกเดี่ยวใน Java

Java ตัวอย่างความหลากหลาย

การเปลี่ยนแปลงข้อกำหนดซอฟต์แวร์

มีการเปลี่ยนแปลงในข้อกำหนด ซึ่งเป็นเรื่องปกติในอุตสาหกรรมซอฟต์แวร์ ต้องเพิ่มฟังก์ชันการทำงานสำหรับบัญชีธนาคารพิเศษที่มีวงเงินเบิกเกินบัญชี วงเงินเบิกเกินบัญชีคือบริการที่ลูกค้าสามารถถอนเงินได้มากกว่ายอดเงินคงเหลือในบัญชี วิธีการถอนเงินสำหรับบัญชีพิเศษนี้จำเป็นต้องมีการเขียนโค้ดใหม่ทั้งหมด ในขณะที่โค้ดที่ทดสอบแล้วในบัญชีออมทรัพย์และบัญชีกระแสรายวันยังคงเหมือนเดิม การแยกส่วนนี้เป็นข้อดีของ OOPS.

Java ความหลากหลาย

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

Java ความหลากหลาย

ขั้นตอน 2) เมื่อมีการเรียกใช้เมธอดถอนเงินสำหรับบัญชีพิเศษ (วงเงินเบิกเกินบัญชี) เมธอดถอนเงินที่กำหนดไว้ในคลาสพิเศษจะถูกเรียกใช้งาน การส่งคำสั่งนี้คือ ความหลากหลายทางรูปแบบใน OOPs.

Java ความหลากหลาย

วิธีการเอาชนะใน Java

การเขียนทับเมธอด (Method Overriding) คือกระบวนการกำหนดนิยามใหม่ของเมธอดในคลาสแม่ภายในคลาสลูก โดยที่คลาสลูกจะยังคงรักษาคุณสมบัติเดิมไว้tracแต่จะนำเสนอการใช้งานใหม่ที่จะถูกเลือกเมื่อโปรแกรมทำงาน

กฎเกณฑ์สำหรับการเอาชนะวิธีการ

  • ลายเซ็นของเมธอด ซึ่งได้แก่ ชื่อเมธอด รายการพารามิเตอร์ และประเภทค่าส่งคืน จะต้องตรงกันทุกประการ
  • เมธอดที่ถูกเขียนทับสามารถขยายขอบเขตการเข้าถึงได้ แต่ไม่สามารถจำกัดขอบเขตได้ หากเมธอดนั้นเป็นแบบ private ในคลาสพื้นฐาน คลาสลูกสามารถทำให้เป็นแบบ public ได้ แต่ในทางกลับกันทำไม่ได้

กฎสำหรับการเอาชนะวิธีการใน Java

ตัวอย่าง

class Doctor{
  public void treatPatient(){
  // treatPatient method
  
}
class Surgeon extends Doctor{
  public void treatPatient(){
  // treatPatient method
  }
}
class Run{
  public static void main (String args[]){
    Doctor doctorObj = new Doctor();
    // treatPatient method in class Doctor will be executed
    doctorObj.treatPatient();
   
    Surgeon surgeonObj = new Surgeon();
    // treatPatient method in class Surgeon will be executed
    surgeonObj.treatPatient();
  }
}

ความแตกต่างระหว่างการโอเวอร์โหลดเมธอดและการโอเวอร์ไรด์เมธอด

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

วิธีการโอเวอร์โหลด
วิธีการเอาชนะ
Method Overloading คือกลไกภายในของคลาสเดียวกัน ที่ซึ่งเมธอดมากกว่าหนึ่งเมธอดมีชื่อเดียวกัน แต่มีรูปแบบการเรียกใช้ (signature) ที่แตกต่างกัน การเขียนทับเมธอด (Method Overriding) คือการที่คลาสย่อยเขียนนิยามใหม่ของเมธอดหนึ่งในคลาสแม่ ในกรณีนี้ รูปแบบการเรียกใช้เมธอดจะยังคงเหมือนเดิม
Ex:

void sum (int a , int b);
void sum (int a , int b, int c);
void sum (float a, double b);
Ex:

class X{
  public int sum(){
     // some code
  }
}
class Y extends X{
  public int sum(){
    //overridden method
    //signature is same
 }
}

Dynamic Polymorphism คืออะไร?

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

ตัวอย่างโพลีมอร์ฟิซึมแบบไดนามิก

ตัวแปรอ้างอิงของคลาสแม่สามารถอ้างอิงถึงอ็อบเจ็กต์ของคลาสลูกได้:

 Doctor obj = new Surgeon();

ลองพิจารณาข้อความต่อไปนี้:

obj.treatPatient();

นี่คือตัวแปรอ้างอิง obj ตัวแปรนั้นเป็นของคลาสแม่ แต่ตัวชี้ไปยังวัตถุนั้นเป็นของคลาสลูก ดังแสดงในแผนภาพของโพลีมอร์ฟิซึม

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

ความแตกต่างระหว่างโพลีมอร์ฟิซึมแบบคงที่และแบบไดนามิก

ความหลากหลายแบบคงที่ใน Java Polymorphism แบบ `constructed` คือรูปแบบหนึ่งของ polymorphism ที่รวบรวมข้อมูลสำหรับการเรียกใช้เมธอดในระหว่างการคอมไพล์ ในขณะที่ Dynamic Polymorphism คือรูปแบบหนึ่งของ polymorphism ที่รวบรวมข้อมูลสำหรับการเรียกใช้เมธอดในระหว่างการทำงานของโปรแกรม

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

Ex:

void sum (int a , int b);
void sum (float a, double b);
int sum (int a, int b); //compiler gives error.
เมื่อตัวแปรอ้างอิงเรียกใช้เมธอดที่ถูกเขียนทับ เมธอดที่จะถูกเรียกใช้จะถูกกำหนดโดยอ็อบเจ็กต์ที่ตัวแปรอ้างอิงชี้ไป ซึ่งสามารถกำหนดได้เฉพาะในระหว่างการทำงานของโค้ดเท่านั้น นั่นคือเหตุผลที่ชื่อเมธอดเป็นแบบไดนามิก

Ex:

//reference of parent pointing to child object
 Doctor obj = new Surgeon();
// method of child called
obj.treatPatient();

ซูเปอร์คีย์เวิร์ดใน Java

แล้วถ้าเมธอด treatPatient ในคลาส Surgeon ต้องการเรียกใช้ฟังก์ชันที่กำหนดไว้ในคลาส Doctor แล้วจึงดำเนินการพฤติกรรมเฉพาะของตัวเองล่ะ? ในกรณีนี้ คำสำคัญคืออะไร? super สามารถใช้เพื่อเข้าถึงวิธีการของคลาสหลักจากคลาสย่อยได้ วิธีการ treatPatient ในคลาส Surgeon สามารถเขียนได้ดังนี้:

treatPatient(){
   super.treatPatient();
     //add code specific to Surgeon
}

คีย์เวิร์ด `super` สามารถใช้เพื่อเข้าถึงสมาชิกข้อมูลหรือเมธอดใดๆ ของคลาสแม่ภายในคลาสลูกได้ ต่อไปเราจะมาเรียนรู้เกี่ยวกับคีย์เวิร์ด `super` กัน มรดกและภาวะพหุรูปใน Java พร้อมตัวอย่างโปรแกรม

ตัวอย่าง: เพื่อเรียนรู้เรื่องการสืบทอด (Inheritance), พหุรูป (Polymorphism) และคำหลัก super

ขั้นตอน 1) คัดลอกโค้ดต่อไปนี้ลงในโปรแกรมแก้ไข

public class Test{
     public static void main(String args[]){
        X x= new X();
        Y y = new Y();
        y.m2();
        //x.m1();
        //y.m1();
        //x = y;// parent pointing to object of child
        //x.m1() ;
        //y.a=10;
   }
}
class X{
   private int a;
   int b;
      public void m1(){
       System.out.println("This is method m1 of class X");
     }
}
class Y extends X{
      int c; // new instance variable of class Y
         public void m1(){
            // overridden method
            System.out.println("This is method m1 of class Y");
        }
       public void m2(){
           super.m1();
           System.out.println("This is method m2 of class Y");
      }
}

ขั้นตอน 2) บันทึก คอมไพล์ และรันโค้ด สังเกตผลลัพธ์

ขั้นตอน 3) ลบเครื่องหมายคอมเมนต์ออกจากบรรทัดที่ 6 ถึง 9 บันทึก คอมไพล์ และรันโค้ด สังเกตผลลัพธ์

ขั้นตอน 4) ลบเครื่องหมายคอมเมนต์ออกจากบรรทัดที่ 10 บันทึกและคอมไพล์โค้ด

ขั้นตอน 5) ข้อผิดพลาด = ? เนื่องจากคลาสย่อยไม่สามารถเข้าถึงสมาชิกส่วนตัวของคลาสแม่ได้

คำถามที่พบบ่อย

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

Java รองรับโพลีมอร์ฟิซึมในขั้นตอนการคอมไพล์ผ่านการโอเวอร์โหลดเมธอด (Method Overloading) และโพลีมอร์ฟิซึมในขั้นตอนการรันไทม์ผ่านการโอเวอร์ไรด์เมธอด (Method Overriding) การโอเวอร์โหลดจะแก้ไขปัญหาในขั้นตอนการคอมไพล์ผ่านการผูกแบบสแตติก (Static binding) ในขณะที่การโอเวอร์ไรด์จะแก้ไขปัญหาในขั้นตอนการรันไทม์ผ่านการผูกแบบไดนามิก (Dynamic binding) ซึ่งจัดการโดย JVM

การผูกแบบคงที่ (Static binding) เชื่อมโยงการเรียกใช้เมธอดกับคำจำกัดความของเมธอดนั้นในระหว่างการคอมไพล์ และใช้สำหรับการโอเวอร์โหลดเมธอด (Method Overloading) การผูกแบบไดนามิก (Dynamic binding) เชื่อมโยงการเรียกใช้ในระหว่างการทำงานโดยอิงจากประเภทของอ็อบเจ็กต์จริง และเป็นพื้นฐานสำหรับการโอเวอร์ไรด์เมธอด (Method Overriding) Java.

คีย์เวิร์ด `super` ช่วยให้คลาสย่อยสามารถเรียกใช้เมธอดที่ถูกเขียนทับหรือเข้าถึงสมาชิกข้อมูลจากคลาสแม่ได้ ซึ่งทำให้คลาสลูกสามารถนำตรรกะของคลาสแม่มาใช้ซ้ำได้ แล้วจึงเพิ่มพฤติกรรมเฉพาะทางเข้าไปเพิ่มเติม

ผู้สอน AI เช่น ChatGPT และ GitHub Copilot Chat สามารถอธิบาย Polymorphism ได้ Java ด้วยการเปรียบเทียบที่กำหนดเอง สร้างโจทย์ฝึกหัด อธิบายขั้นตอนการสืบทอด และทดสอบความรู้ของผู้เรียนเกี่ยวกับ Static binding และ Dynamic binding เพื่อให้เรียนรู้ได้เร็วขึ้น

ใช่แล้ว เครื่องมือช่วยปรับโครงสร้างโค้ดที่ขับเคลื่อนด้วย AI เช่น Cursor, Sourcegraph Cody และ IntelliJ AI Assistant สามารถตรวจจับเงื่อนไขที่ซ้ำกัน เสนอโครงสร้างลำดับชั้นของคลาส และเขียนโค้ดเดิมขึ้นใหม่ได้ Java เขียนโค้ดเพื่อให้การเขียนทับเมธอด (Method Overriding) เข้ามาแทนที่การใช้คำสั่ง if-else ซ้ำๆ กัน

สรุปโพสต์นี้ด้วย: