CodeGym /จาวาบล็อก /สุ่ม /การสืบทอดใน Java
John Squirrels
ระดับ
San Francisco

การสืบทอดใน Java

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

นักแสดงหลักของมรดกในภาษาชวา

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

มันทำงานอย่างไร

สายโซ่การสืบทอดนั้นโดยตรงจากคลาสที่เป็นนามธรรมที่สุดไปยังคลาสที่เป็นรูปธรรมมากขึ้น นั่นคือซุปเปอร์คลาสนั้นเป็นนามธรรมที่สุดในสายของคลาส มักจะแสดงเป็นนามธรรม (คลาสพื้นฐานที่ไม่ต้องมีการใช้งาน) ชั้นเรียนเพิ่มเติมทั้งหมดมีความเฉพาะเจาะจงมากขึ้น เช่น มีคลาสชื่อ “Gadget” อาจมีฟิลด์ (หรือสถานะ) ความจุของแบตเตอรี่ของฟิลด์ "น้ำหนัก" ระดับการชาร์จของฟิลด์ และวิธีการ (หรือพฤติกรรม) "งาน" และการชาร์จ ในกรณีนี้ วิธีการอาจเป็นนามธรรม กล่าวคือ ไม่มีการใช้งานที่เฉพาะเจาะจง แม้ว่าเราจะบอกไม่ได้ว่าเป็นอุปกรณ์ประเภทใด แต่ก็เป็นอุปกรณ์ที่สามารถชาร์จใหม่ได้อย่างแน่นอน มาสร้างคลาสย่อย Phone ของคลาส Gadget กันดีกว่า ไม่จำเป็นต้องกำหนดน้ำหนักและแบตเตอรี่ใหม่อีกต่อไป เพียงแต่สืบทอดมาจากอุปกรณ์ที่เป็นนามธรรม แต่พฤติกรรมการทำงานจะต้องมีการชี้แจง คุณยังสามารถเพิ่มฟิลด์อื่นๆ “แนวทแยงของหน้าจอ”, ตัวเชื่อมต่อ และอื่นๆ ได้อีกด้วย คุณสามารถเพิ่มวิธีการใหม่ “อัปเดตระบบปฏิบัติการ” ได้ ต่อไป เราสามารถสร้างอีกสองคลาสได้ และทั้งสองคลาสจะสืบทอดมาจากโทรศัพท์, Android และ iPhone ทั้งสองคลาสสืบทอดช่องและวิธีการทั้งหมดของ Gadget และสมาร์ทโฟน และวิธีการดังกล่าวสามารถแทนที่ได้ ชั้นหนึ่งต้องการฟิลด์ "ชื่อแบรนด์" ในขณะที่ iPhone ไม่ต้องการฟิลด์นี้ เนื่องจากมีบริษัทเดียวเท่านั้นที่ผลิตสมาร์ทโฟนดังกล่าว
class Gadget {}
}
//subclass of Gadget class
class Phone extends Gadget {}
//subclass of Phone class
class IPhone extends Phone {}
//subclass of Phone class
class AndroidPhone extends Phone {}
คลาสลูกสืบทอดสมาชิกสาธารณะและสมาชิกที่ได้รับการคุ้มครองของคลาสพาเรนต์ มันไม่สำคัญว่าคลาสย่อยจะอยู่ในแพ็กเกจใด หากคลาสลูกอยู่ในแพ็คเกจเดียวกันกับคลาสพาเรนต์ ก็จะสืบทอดสมาชิกแพ็กเกจส่วนตัวของพาเรนต์ด้วย คุณสามารถใช้สมาชิกที่สืบทอดมาตามที่เป็นอยู่ แทนที่ ซ่อน หรือเพิ่มสมาชิกใหม่:
  • คุณสามารถใช้ฟิลด์ที่สืบทอดได้โดยตรง เช่น ฟิลด์อื่นๆ
  • คุณสามารถประกาศฟิลด์ในคลาสลูกที่มีชื่อเหมือนกับในคลาสพาเรนต์ได้ มันกำลังซ่อนมันอยู่ (ดังนั้นอย่าทำจะดีกว่า)
  • คุณสามารถประกาศฟิลด์ใหม่ในคลาสย่อยได้ (ฟิลด์ที่คลาสพาเรนต์ไม่มี)
  • วิธีการสืบทอดสามารถนำมาใช้โดยตรงโดยไม่ต้องแทนที่ในคลาสที่ได้รับ
  • นอกจากนี้ คุณยังสามารถเขียนวิธีการอินสแตนซ์ใหม่ในคลาสย่อยที่มีลายเซ็นเหมือนกับวิธีการในคลาสพาเรนต์ได้ ขั้นตอนนี้จะแทนที่มัน
  • คุณสามารถประกาศวิธีการใหม่ในคลาสลูกที่ไม่ได้ประกาศในคลาส Parent
  • คุณสามารถเขียนตัวสร้างคลาสย่อยที่เรียกตัวสร้างคลาสระดับสูงโดยปริยายหรือด้วยคีย์เวิร์ด super

ตัวอย่าง

มาสร้างคลาส MusicalInstrument พื้นฐานพร้อมช่องน้ำหนักและเครื่องหมายการค้า รวมถึงเมธอดwork() กัน เรายังกำหนดตัวสร้าง
public class MusicalInstrument {
   int weight;
   String tradeMark;

   public MusicalInstrument(int weight, String tradeMark) {
       this.weight = weight;
       this.tradeMark = tradeMark;
   }

   public void work() {
       System.out.println("the instrument is playing...");
   }
}
ยังไม่ชัดเจนว่าเป็นเครื่องดนตรีชนิดใดและเล่นอย่างไร มาสร้างเครื่องดนตรีที่เฉพาะเจาะจงกว่านี้กันดีกว่า ไวโอลิน มันจะมีฟิลด์เหมือนกับในเครื่องดนตรี (พวกมันจะถูกเรียกในตัวสร้างโดยใช้คีย์เวิร์ด super นอกจากนี้เรายังสามารถแทนที่วิธีการทำงานและสร้างวิธีการตั้งค่าสายไวโอลินด้วยสตริงได้
public class Violin extends MusicalInstrument {
   String master;
   String owner;
   int age;
   boolean isTuned;

   public Violin(int weight, String tradeMark, String master, String owner, int age, boolean isTuned) {
       super(weight, tradeMark);
       this.master = master;
       this.owner = owner;
       this.age = age;
       this.isTuned = isTuned;
   }

   @Override
   public void work() {
       System.out.println("THe violin's playing");

   }

   public void violinTuning () {
     System.out.println("I'm tuning 1st string...");
     System.out.println("I'm tuning 2nd string...");
     System.out.println("I'm tuning 3rd string...");
     System.out.println("I'm tuning 4th string...");
}


}
มาสร้าง คลาส สาธิตเพื่อทดสอบ คลาส ไวโอลินและดูว่าการสืบทอดทำงานอย่างไร
public class InheritDemo {

   public static void main(String[] args) {

       Violin violin = new Violin(1, null, "Amati", "Kremer", 285, false);
       violin.violinTuning();
       violin.work();
   }
}
ในกรณีนี้ ผลลัพธ์ของโปรแกรมจะเป็นดังนี้:
ฉันกำลังจูนสาย 1 ฉันกำลังจูนสาย 2 ฉันกำลังจูนสาย 3 ฉันกำลังจูนสาย 4 กำลังเล่นไวโอลิน
นั่นคือถ้ามีเมธอดที่ถูกแทนที่ในคลาสย่อย เมธอดระดับบนจะไม่ถูกเรียกอีกต่อไป เกิดอะไรขึ้นถ้ามันไม่ได้อยู่ที่นั่น? นั่นคือคลาสไวโอลินมีลักษณะดังนี้:
public class Violin extends MusicalInstrument {
   String master;
   String owner;
   int age;
   boolean isTuned;

   public Violin(int weight, String tradeMark, String master, String owner, int age, boolean isTuned) {
       super(weight, tradeMark);
       this.master = master;
       this.owner = owner;
       this.age = age;
       this.isTuned = isTuned;
   }

  // @Override


 //  }

   public void violinTuning () {
       System.out.println("I'm tuning 1st string...");
       System.out.println("I'm tuning 2nd string...");
       System.out.println("I'm tuning 3rd string...");
       System.out.println("I'm tuning 4th string...");
   }

}
ผลลัพธ์คือ:
ฉันกำลังจูนสาย 1... ฉันกำลังจูนสาย 2... ฉันกำลังจูนสาย 3... ฉันกำลังจูนสาย 4... เครื่องดนตรีกำลังเล่น...
นั่นคือวิธีบรรพบุรุษจะถูกเรียกโดยอัตโนมัติ อย่างไรก็ตาม คลาสย่อยสามารถกำหนดได้ผ่านทางบรรพบุรุษ นั่นคือ เพื่อทำการอัปแคสต์:
Parent parent = new Child()
การเริ่มต้นนี้ใช้เพื่อเข้าถึงเฉพาะสมาชิกที่อยู่ในคลาสพาเรนต์และวิธีการแทนที่ ในตัวอย่างของเรามันจะเป็น:
public class InheritDemo {

   public static void main(String[] args) {

       MusicalInstrument violin = new Violin(1, null, "Amati", "Kremer", 285, false);
       //violin.violinTuning();
       violin.work();
   }
}
ในกรณีเช่นนี้ เราไม่สามารถกำหนดค่าวิธีไวโอลินได้ อย่างไรก็ตาม ในเวลาเดียวกัน เมธอดwork()ของคลาสสืบทอดจะถูกเรียก หากมีอยู่

ลำดับชั้นของคลาสแพลตฟอร์ม Java

ใน Java ทุกอย่างประกอบด้วยคลาสและอยู่ภายใต้ลำดับชั้น คำถามเกิดขึ้น: มีคลาสที่คลาสอื่นสืบทอดมาหรือไม่? คำตอบคือ ใช่ มีชั้นเรียนเช่นนี้อยู่จริง และเรียกง่ายๆว่าObject คลาสObjectจากแพ็คเกจ java.lang กำหนดและปรับใช้ลักษณะการทำงานทั่วไปสำหรับทุกคลาส รวมถึงคลาสที่คุณสร้างขึ้นด้วย ในแพลตฟอร์ม Java คลาสจำนวนมากได้รับมาจากObject โดยตรง คลาสอื่นๆ มาจากคลาสเหล่านี้บางคลาส และอื่นๆ โดยสร้างลำดับชั้นของคลาส

ประเภทของมรดกในภาษา Java

เรามาเน้นการสืบทอดบางประเภทใน Java กันดีกว่า 1. Single Inheritance ประเภทนี้เหมือนกับในตัวอย่างด้านบน คลาสย่อยสืบทอดคุณสมบัติของซูเปอร์คลาสหนึ่งคลาส ในภาพด้านล่าง คลาส A ทำหน้าที่เป็นคลาสพื้นฐานสำหรับคลาสที่ได้รับ B 2. การสืบทอดหลายระดับ นี่เป็นเพียงสายโซ่ของการสืบทอด นั่นคือ มีคลาสพื้นฐาน A คลาส B ได้รับการสืบทอดจากมัน และคลาส C ได้รับการสืบทอดมาจากคลาส B ใน Java คลาสไม่สามารถเข้าถึงสมาชิกของปู่ย่าตายายได้โดยตรง 3. การสืบทอดแบบลำดับชั้น ในการสืบทอดแบบลำดับชั้น คลาสหนึ่งทำหน้าที่เป็นคลาสซุปเปอร์ (คลาสพื้นฐาน) สำหรับคลาสย่อยมากกว่าหนึ่งคลาส ด้านบน เราได้ยกตัวอย่างคลาส Phone ซึ่งสามารถมี "ลูก" ได้สองตัว ได้แก่ AndroidPhone และ IPhone
class A {
    public void printA() {
System.out.println("A");
 }
}

class B extends A {
    public void printB() {
 System.out.println(" B"); }
}

class C extends A {
    public void printC() {
System.out.println("C");
}
}

class D extends A {
    public void printD() {
System.out.println("D");
 }
}

public class Demo {
    public static void main(String[] args)
    {
        B objB = new B();
        objB.printA();
        objB.printB();

        C objC = new C();
        objC.printA();
        objC.printC();

        D objD = new D();
        objD.printA();
        objD.printD();
    }
}
ผลลัพธ์คือ:
เอ บี เอ ซี เอ ดี
4. การสืบทอดหลายรายการ นั่นคือ การมีอยู่ของบรรพบุรุษหลายคน ... แต่เดี๋ยวก่อน Java ไม่รองรับการสืบทอดหลายรายการแบบคลาสสิก ในระดับหนึ่งสามารถนำไปใช้ได้โดยใช้ไม่ใช่คลาส แต่ใช้อินเทอร์เฟซ
interface A {
   public void printA();
}

interface B {
   public void printB();
}

interface C extends A, B {
   public void print();
}
class InheritDemo implements C {
   @Override
   public void print()
   {
       System.out.println("Print something");
   }

   @Override
   public void printA() {
   }

   @Override
   public void printB() {
   }
}
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION