CodeGym /จาวาบล็อก /สุ่ม /ตัวสร้างคลาสพื้นฐาน
John Squirrels
ระดับ
San Francisco

ตัวสร้างคลาสพื้นฐาน

เผยแพร่ในกลุ่ม
สวัสดี! ครั้งที่แล้วเราได้พูดคุยเกี่ยวกับตัวสร้างและเรียนรู้มากมายเกี่ยวกับพวกเขา ตอนนี้เราจะพูดถึง ตัวสร้าง คลาส พื้นฐาน
ตัวสร้างคลาสพื้นฐาน - 1
คลาสพื้นฐาน คืออะไร? เกี่ยวข้องกับความจริงที่ว่าใน Java หลายคลาสที่แตกต่างกันสามารถมีจุดกำเนิดร่วมกันได้
ตัวสร้างคลาสพื้นฐาน - 2
สิ่งนี้เรียกว่ามรดก คลาสลูกหลายคลาสสามารถมีบรรพบุรุษร่วมกันได้หนึ่งคน ตัวอย่างเช่น สมมติว่าเรามีAnimalชั้นเรียน:

public class Animal {
  
   String name;
   int age;
}
เราสามารถประกาศคลาสลูกได้ 2 คลาส: Catและ Dogทำได้โดยใช้คำหลัก expands

public class Cat extends Animal {

}

public class Dog extends Animal {
  
}
เราอาจพบว่าสิ่งนี้มีประโยชน์ในอนาคต ตัวอย่างเช่น หากมีงานให้จับหนู เราจะสร้างวัตถุ Cat ในโปรแกรมของเรา หากภารกิจคือการไล่ตามไม้เราจะใช้ Dog วัตถุ และถ้าเราสร้างโปรแกรมที่จำลองคลินิกสัตวแพทย์ มันจะทำงานร่วมกับAnimal ชั้นเรียน (และสามารถรักษาทั้งแมวและสุนัข) สิ่งสำคัญคือต้องจำไว้ว่าเมื่อสร้างวัตถุ ตัวสร้างของคลาสพื้นฐานจะถูกเรียกเป็นอันดับแรก หลังจากที่คอนสตรัคเตอร์นั้นเสร็จสิ้น โปรแกรมจะดำเนินการคอนสตรัคเตอร์ของคลาสที่สอดคล้องกับวัตถุที่เรากำลังสร้าง กล่าวอีกนัยหนึ่ง เมื่อสร้างCatวัตถุตัวAnimalสร้างจะทำงานก่อนและหลังจากนั้นคือ theCatตัวสร้างดำเนินการ หากต้องการดูสิ่งนี้ ให้เพิ่มเอาต์พุตของคอนโซลไปยังตัว สร้าง CatและAnimalตัวสร้าง

public class Animal {

   public Animal() {
       System.out.println("Animal constructor executed");
   }
}


public class Cat extends Animal {

   public Cat() {
       System.out.println("Cat constructor executed!");
   }

   public static void main(String[] args) {
       Cat cat = new Cat();
   }
}
เอาต์พุตของคอนโซล: ตัวสร้างสัตว์ดำเนินการ ตัวสร้างแมวดำเนินการแล้ว! แน่นอนมันทำงานอย่างนั้น! ทำไม เหตุผลประการหนึ่งคือการหลีกเลี่ยงฟิลด์ที่ซ้ำกันที่ใช้ร่วมกันระหว่างสองคลาส ตัวอย่างเช่น สัตว์ทุกตัวมีหัวใจและสมอง แต่ไม่ใช่สัตว์ทุกตัวที่มีหาง เราสามารถประกาศ ฟิลด์ สมองและหัวใจซึ่งเป็นเรื่องปกติสำหรับสัตว์ทุกชนิดในAnimalคลาสพ่อแม่ และ ฟิลด์ หางในCatคลาสย่อย . ตอนนี้เราจะประกาศCatตัวสร้างคลาสที่รับอาร์กิวเมนต์สำหรับฟิลด์ทั้ง 3

public class Cat extends Animal {

   String tail;

   public Cat(String brain, String heart, String tail) {
       this.brain = brain;
       this.heart = heart;
       this.tail = tail;
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
หมายเหตุ:ตัวสร้างทำงานได้อย่างถูกต้องแม้ว่าคลาสCatจะไม่มีช่องสมองและหัวใจ ฟิลด์เหล่านี้ "สืบทอด" จากAnimalคลาสพื้นฐาน คลาสที่สืบทอดสามารถเข้าถึงฟิลด์ของคลาสพื้นฐานดังนั้นจึงมองเห็นได้ในCatคลาส ของเรา ด้วยเหตุนี้ เราจึงไม่จำเป็นต้องทำซ้ำฟิลด์เหล่านี้ในCatชั้นเรียน เราสามารถนำมาจากAnimalชั้นเรียน ยิ่งไปกว่านั้น เราสามารถเรียกตัวสร้างคลาสพื้นฐานในตัวสร้างคลาสลูกได้อย่างชัดเจน คลาสพื้นฐานเรียกอีกอย่างว่า " ซูเปอร์คลาส " นั่นเป็นเหตุผลที่ Java ใช้คำหลักsuperเพื่อระบุคลาสพื้นฐาน ในตัวอย่างก่อนหน้านี้

public Cat(String brain, String heart, String tail) {
       this.brain = brain;
       this.heart = heart;
       this.tail = tail;
   }
เรากำหนดแต่ละฟิลด์แยกกันในคลาสหลักของเรา เราไม่จำเป็นต้องทำเช่นนี้ การเรียกตัวสร้างคลาสพาเรนต์และส่งผ่านอาร์กิวเมนต์ที่จำเป็นก็เพียงพอแล้ว:

public class Animal {

   String brain;
   String heart;

   public Animal(String brain, String heart) {
       this.brain = brain;
       this.heart = heart;
   }

public class Cat extends Animal {

   String tail;

   public Cat(String brain, String heart, String tail) {
       super(brain, heart);
       this.tail = tail;
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
ในCatตัวสร้าง เราเรียกAnimalตัวสร้างและผ่านสองช่อง เรามีฟิลด์เดียวที่จะเริ่มต้นอย่างชัดเจน: tailซึ่งไม่ได้อยู่Animalใน จำได้ไหมว่าเราพูดถึงว่าตัวสร้างคลาสพาเรนต์ถูกเรียกเป็นอันดับแรกเมื่อสร้างออบเจกต์ นั่นเป็นเหตุผลที่super() ควรเป็นอันดับแรกในตัวสร้างเสมอ! มิฉะนั้น ตรรกะของตัวสร้างจะถูกละเมิดและโปรแกรมจะสร้างข้อผิดพลาด

public class Cat extends Animal {

   String tail;

   public Cat(String brain, String heart, String tail) {
       this.tail = tail;
       super(brain, heart);// Error!
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
คอมไพลเลอร์รู้ว่าเมื่อสร้างวัตถุของคลาสลูก ตัวสร้างคลาสพื้นฐานจะถูกเรียกใช้ก่อน และหากคุณพยายามเปลี่ยนลักษณะการทำงานนี้ด้วยตนเอง คอมไพเลอร์จะไม่อนุญาต

วิธีสร้างวัตถุ

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

public class Animal {

   String brain = "Initial value of brain in the Animal class";
   String heart = "Initial value of heart in the Animal class";

   public static int animalCount = 7700000;

   public Animal(String brain, String heart) {
       System.out.println("Animal base class constructor is running");
       System.out.println("Have the variables of the Animal class already been initialized?");
       System.out.println("Current value of static variable animalCount = " + animalCount);
       System.out.println("Current value of brain in the Animal class = " + this.brain);
       System.out.println("Current value of heart in the Animal class = " + this.heart);
       System.out.println("Have the variables of the Cat class already been initialized?");
       System.out.println("Current value of static variable catCount = " + Cat.catCount);

       this.brain = brain;
       this.heart = heart;
       System.out.println("Animal base class constructor is done!");
       System.out.println("Current value of brain = " + this.brain);
       System.out.println("Current value of heart = " + this.heart);
   }
}

public class Cat extends Animal {

   String tail = "Initial value of tail in the Cat class";

   static int catCount = 37;

   public Cat(String brain, String heart, String tail) {
       super(brain, heart);
       System.out.println("The cat class constructor has started (The Animal constructor already finished)");
       System.out.println("Current value of static variable catCount = " + catCount);
       System.out.println("Current value of tail = " + this.tail);
       this.tail = tail;
       System.out.println("Current value of tail = " + this.tail);
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
ดังนั้นเราจึงสร้างตัวอย่างใหม่ของCatคลาสซึ่งสืบทอดAnimal. เราได้เพิ่มเอาต์พุตคอนโซลแบบละเอียดเพื่อดูว่ามีอะไรเกิดขึ้นบ้างและเรียงลำดับอย่างไร นี่คือสิ่งที่จะแสดงเมื่อCatสร้างวัตถุ: ตัวสร้างคลาส Animal base กำลังทำงาน มีการกำหนดค่าตัวแปรของคลาส Animal แล้วหรือยัง ค่าปัจจุบันของตัวแปรสแตติก animalCount = 7700000 ค่าปัจจุบันของสมองในคลาสสัตว์ = ค่าเริ่มต้นของสมองในคลาสสัตว์ ค่าปัจจุบันของหัวใจในคลาสสัตว์ = ค่าเริ่มต้นของหัวใจในคลาสสัตว์ มีตัวแปรของคลาสแมวอยู่แล้ว ได้รับการเริ่มต้น? ค่าปัจจุบันของตัวแปรสแตติก catCount = 37 ตัวสร้างคลาสฐานสัตว์เสร็จแล้ว! ค่าปัจจุบันของสมอง = สมอง ค่าปัจจุบันของหัวใจ = หัวใจ ตัวสร้างคลาส cat ได้เริ่มต้นขึ้น (ตัวสร้างสัตว์เสร็จสิ้นแล้ว) ค่าปัจจุบันของตัวแปรคงที่ catCount = 37 ค่าปัจจุบันของหาง = ค่าเริ่มต้นของหางในคลาส Cat ค่าปัจจุบันของหาง = หาง ตอนนี้เราสามารถเห็นลำดับของการกำหนดค่าเริ่มต้นตัวแปรและการเรียกใช้ตัวสร้างได้อย่างชัดเจนเมื่อสร้างวัตถุใหม่:
  1. ตัวแปรส แตติกของคลาสฐาน ( Animal) จะถูกเตรียมใช้งาน ในกรณีของเราAnimalCountAnimalตัวแปรของคลาสถูกตั้งค่าเป็น 7700000

  2. ตัวแปรส แตติกของคลาสลูก ( Cat) จะถูกเตรียมใช้งาน

    หมายเหตุ:เรายังคงอยู่ในAnimalตัวสร้างและเราได้แสดงไว้แล้ว:

    ตัวสร้างคลาส Animal base กำลังทำงาน
    มีการกำหนดค่าตัวแปรของคลาส Animal แล้วหรือยัง
    ค่าปัจจุบันของตัวแปรสแตติก animalCount = 7700000
    ค่าปัจจุบันของสมองในคลาสสัตว์ = ค่าเริ่มต้นของสมองในคลาสสัตว์ ค่าปัจจุบันของ
    หัวใจในคลาสสัตว์ = ค่าเริ่มต้นของหัวใจในคลาสสัตว์
    มีตัวแปรของคลาสแมวอยู่แล้ว ได้รับการเริ่มต้น?
    ค่าปัจจุบันของตัวแปรคงที่ catCount = 37


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

    ตัวสร้างคลาส Animal base กำลังทำงาน
    มีการกำหนดค่าตัวแปรของคลาส Animal แล้วหรือยัง
    ค่าปัจจุบันของตัวแปรคงที่ animalCount = 7700000
    ค่าปัจจุบันของสมองในคลาสสัตว์ = ค่าเริ่มต้นของสมองในคลาสสัตว์
    ค่าปัจจุบันของหัวใจในคลาสสัตว์ = ค่าเริ่มต้นของหัวใจในคลาสสัตว์


  4. ตัวสร้างคลาสพื้นฐานเริ่มต้นขึ้น
    เรามั่นใจตัวเองแล้วว่าขั้นตอนนี้เป็นขั้นตอนที่สี่: ในสามขั้นตอนแรกที่จุดเริ่มต้นของAnimalคอนสตรัคเตอร์ ตัวแปรจำนวนมากได้ถูกกำหนดค่าไว้แล้ว


  5. ฟิลด์ที่ไม่คงที่ของคลาส ย่อย ( Cat) จะถูกเตรียมใช้งาน
    สิ่งนี้จะเกิดขึ้นก่อนที่Catตัวสร้างจะเริ่มทำงาน
    เมื่อเริ่มทำงาน ตัวแปรหางมีค่าอยู่แล้ว:

    ตัวสร้างคลาส cat เริ่มต้นแล้ว (ตัวสร้าง Animal เสร็จสิ้นแล้ว) ค่าปัจจุบันของตัวแปรคงที่ catCount = 37 ค่าปัจจุบันของหาง = ค่าเริ่มต้นของหางในคลาส Cat


  6. คอนสตรัคเตอร์ของCatคลาสลูกเรียกว่า

    และนั่นคือลักษณะของการสร้างวัตถุใน Java!

    ฉันต้องบอกว่าเราไม่ใช่แฟนตัวยงของการเรียนรู้แบบท่องจำ แต่เป็นการดีที่สุดที่จะจดจำลำดับของการเริ่มต้นตัวแปรและการเรียกใช้ตัวสร้าง

    สิ่งนี้จะช่วยเพิ่มความเข้าใจของคุณเกี่ยวกับโฟลว์ของโปรแกรม และสถานะของออบเจกต์ของคุณในช่วงเวลาใดเวลาหนึ่ง

    ยิ่งไปกว่านั้น คลาสจำนวนมากไม่ได้ใช้การสืบทอด ในกรณีนี้ จะไม่ใช้ขั้นตอนที่เกี่ยวข้องกับคลาสพื้นฐาน

อ่านเพิ่มเติม:

ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION