เมื่อเร็วๆ นี้ ฉันมีประสบการณ์ในการกำหนดวัตถุคลาสย่อยให้กับวัตถุคลาสแม่ และฉันต้องการแบ่งปันกับคุณ แต่ระดับของฉันมีจำกัด ดังนั้นโปรดแก้ไขฉันและวิพากษ์วิจารณ์ฉันด้วย
ใกล้บ้าน นี่คือตัวอย่างเล็กๆ น้อยๆ โปรดดู
ทดสอบอันหนึ่ง
ชั้นเรียนผู้ปกครอง:
คลาสย่อย:
ผลลัพธ์: นี่คือเมธอด print() ของคลาสพาเรนต์ - อ็อบเจ็กต์ในขณะนี้คือ Subclass@126b249
ในขณะนี้ อ็อบเจ็กต์คือ Subclass@126b249
แสดงให้เห็น:
Supclass sup=คลาสย่อยใหม่();
แม้ว่าวัตถุที่ประกาศเป็นวัตถุคลาสหลัก พื้นที่หน่วยความจำจริงเป็นของวัตถุคลาสย่อย
เมธอด public void print() ที่สืบทอดมาจากคลาสพาเรนต์ถูกเรียก และผลลัพธ์คือการจำแนกชื่อของอ็อบเจ็กต์คลาสย่อย
สรุป: วัตถุที่ประกาศในเวลาคอมไพล์เป็นวัตถุคลาสหลัก แต่ ณ รันไทม์มันเป็นวัตถุคลาสย่อย หากคลาสย่อยไม่ได้แทนที่วิธีการของคลาสผู้ปกครอง วัตถุในขณะนี้จะเรียกวิธีที่สืบทอดมาจากคลาสผู้ปกครอง
ทดสอบ 2
ชั้นเรียนผู้ปกครอง:
คลาสย่อย:
ผลลัพธ์: นี่คือเมธอด subclass print() - ขณะนี้อ็อบเจ็กต์คือ Subclass@126b249
ในขณะนี้ อ็อบเจ็กต์คือ Subclass@126b249
แสดงให้เห็น:
จากตัวอย่างก่อนหน้านี้ ฉันเขียนเมธอด print() ของคลาสพาเรนต์ใหม่ ในขณะนี้ มีการเรียกเมธอด print() ของคลาสย่อย
สรุป: จากข้อสรุปของตัวอย่างก่อนหน้านี้ ฉันมาถึงข้อสรุป: ในเวลานี้ อ็อบเจ็กต์นั้นเป็นอ็อบเจ็กต์คลาสย่อยเมื่อรัน หากคลาสย่อยไม่ได้เขียนเมธอดของคลาสพาเรนต์
จากนั้นอ็อบเจ็กต์ในเวลานี้จะเรียกเมธอดที่สืบทอดมาจากคลาสพาเรนต์ มิฉะนั้น อ็อบเจ็กต์ในเวลานี้จะเรียกเมธอดคลาสย่อย
คำถาม: เราสามารถสรุปข้อสรุปต่อไปนี้จากการทดสอบข้างต้นได้หรือไม่: กำหนดวัตถุคลาสย่อยให้กับวัตถุคลาสแม่ (เช่น Supclass sup=new Subclass())
สิ่งที่เราได้รับคือวัตถุคลาสย่อย กล่าวคือ sup คือวัตถุคลาสย่อย ?????
ทดสอบสาม
ชั้นเรียนผู้ปกครอง:
คลาสย่อย:
ผลลัพธ์: แอ็ตทริบิวต์ในขณะนี้: แอ็ตทริบิวต์คลาสพาเรนต์
หมายเหตุ: จากการทดสอบครั้งแรก ฉันได้เพิ่มแอตทริบิวต์ className ให้กับคลาสพาเรนต์ และแทนที่แอตทริบิวต์นี้ในคลาสย่อย
แต่เมื่อฉันส่งออกคุณสมบัติของอ็อบเจ็กต์ในเวลานี้ มันเป็นคุณสมบัติของคลาสพาเรนต์
สรุป: เมื่อกำหนดออบเจ็กต์คลาสย่อยให้กับออบเจ็กต์คลาสพาเรนต์ วิธีการและคุณสมบัติจะแตกต่างอย่างมากจากความสัมพันธ์แบบสืบทอดดั้งเดิมของเรา
คำถาม:
วัตถุในขณะนี้เป็นวัตถุคลาสย่อยหรือวัตถุคลาสแม่หรือไม่
เริ่มคาดเดา:
มีบางประเด็นที่ฉันต้องทำก่อนที่จะคาดเดา:
1. เมื่อเราสร้างออบเจ็กต์คลาสย่อยใหม่ Constructor ของออบเจ็กต์คลาสพาเรนต์ก็จะถูกดำเนินการในเวลาเดียวกัน นั่นคือข้อมูลที่จำเป็นบางอย่างของคลาสพาเรนต์และออบเจ็กต์คลาสย่อยจะใช้พื้นที่หน่วยความจำเดียวกัน
เมื่อเราแทนที่เมธอดนี้ เราสามารถใช้ super object เพื่ออ้างถึงคลาสพาเรนต์ได้
2. ออบเจ็กต์ใน Java ไม่ได้เป็นเชิงวัตถุอย่างสมบูรณ์ กล่าวคือ คุณลักษณะและวิธีการของออบเจ็กต์ไม่ได้ถูกห่อหุ้มไว้ในออบเจ็กต์ในเวลาเดียวกัน
แต่วัตถุนั้นมีคุณลักษณะของตัวเอง แต่วิธีการอ้างอิงถึงวิธีการในชั้นเรียน อาจกล่าวได้ว่ามันห่อหุ้มการอ้างอิงของคุณลักษณะและวิธีการในชั้นเรียนลงในวัตถุ
ดังนั้นเมธอดที่ถูกเรียกโดยอ็อบเจ็กต์ไม่ใช่เมธอดของตัวเอง แต่เป็นเมธอดในคลาส สำหรับสาเหตุที่ Java ทำสิ่งนี้ ฉันไม่รู้
3. เมื่อโหลดวัตถุลงในหน่วยความจำ คลาสจะถูกโหลดลงในหน่วยความจำก่อน จากนั้นคลาสจะยังคงอยู่ในหน่วยความจำ ส่วนเมื่อใดที่คลาสจะหายไปจากหน่วยความจำ ฉันไม่รู้
ฉันคิดว่า Java ต้องมีกลไกการรีไซเคิลของตัวเอง เช่นเดียวกับการรีไซเคิลวัตถุ
4. การคอมไพล์และการรันเป็นสิ่งที่แตกต่างอย่างสิ้นเชิง สิ่งสำคัญที่คุณทำระหว่างการคอมไพล์คือการประกาศประเภทของออบเจ็กต์ กำหนดแอตทริบิวต์ ตรวจสอบข้อผิดพลาดทางไวยากรณ์ ฯลฯ
สิ่งที่รันไทม์ทำคือโหลดออบเจ็กต์ลงในหน่วยความจำ (โดยปกติจะใช้ใหม่ การสะท้อนก็ใช้กันทั่วไป) เรียกใช้ฟังก์ชันการเรียกใช้โค้ด ฯลฯ
5. หากคุณ ผู้อ่าน และฉันไม่สอดคล้องกันในประเด็นเหล่านี้ หรือถ้าเราไม่มีความเข้าใจในประเด็นเหล่านี้เหมือนกัน คุณจะคิดว่าฉันกำลังพูดเรื่องไร้สาระ
บางทีคุณอาจคิดว่าคะแนนผู้เชี่ยวชาญของฉันต่ำเกินไป ดังนั้นความน่าเชื่อถือของฉันจึงต่ำ แต่สิ่งที่ฉันอยากจะพูดคือไม่มีลำดับการเรียนรู้ และผู้ที่เชี่ยวชาญมาก่อน
ฮ่าๆ ฉันพร้อมเปลี่ยนคะแนนผู้เชี่ยวชาญให้เป็นค่าลบแล้ว ไร้สาระอีกแล้ว ไปกันต่อเลย
การเก็งกำไร:
1. เมื่อเราคอมไพล์ Supclass sup=new Subclass() วัตถุ sup จะถูกประกาศเป็นคลาส Supclass ดังนั้นคุณลักษณะของวัตถุ sup จึงเป็นค่าของคุณลักษณะของวัตถุคลาสหลัก
3. ดำเนินการต่อจากขั้นตอนที่ 2 หากเราแทนที่วิธีการของคลาสพาเรนต์ เนื่องจากพื้นที่หน่วยความจำของวัตถุ sup คือพื้นที่หน่วยความจำของวัตถุคลาสย่อย ดังนั้นวิธีคลาสย่อย public void print() จะถูกโหลดลงในหน่วยความจำ
ดังนั้นสิ่งที่เราเรียกคือเมธอด public void print() ของคลาสย่อย หากคุณต้องการเรียกเมธอดที่ถูกแทนที่ของคลาสพาเรนต์ คุณต้องใช้ super
ข้อความนี้สามารถอธิบายการทดสอบ 2
สรุป:
ต่อไปนี้เป็นความคิดเห็นส่วนตัวล้วนๆ:
กำหนดวัตถุคลาสย่อยให้กับวัตถุคลาสแม่ และวัตถุผลลัพธ์จะเป็นวัตถุเช่นนี้:
มันถูกคอมไพล์เป็นวัตถุคลาสแม่ แต่ทำงานเป็นวัตถุคลาสย่อย ลักษณะเฉพาะมีดังนี้
1. ประกาศเป็นวัตถุคลาสพาเรนต์ 2. มีแอตทริบิวต์คลาสพาเรนต์ 3. ครอบครองพื้นที่หน่วยความจำของคลาสย่อย 4. เมื่อเมธอดคลาสย่อยแทนที่เมธอดคลาสพาเรนต์ วัตถุจะเรียกเมธอดคลาสย่อยในเวลานี้ มิฉะนั้น การสืบทอดจะเป็นไปโดยอัตโนมัติ เรียกว่าเมธอดของคลาสพาเรนต์
5. ฉันคิดว่าวัตถุนี้ไม่ใช่ทั้งวัตถุคลาสแม่หรือวัตถุคลาสย่อย เมื่อเราใช้วิธีการของมัน
ฉันถือว่ามันเป็นวัตถุคลาสย่อย ถ้าฉันใช้คุณสมบัติ ฉันจะถือว่ามันเป็นวัตถุคลาสหลัก
มันเป็นอ็อบเจ็กต์ที่ใช้คุณสมบัติของคลาสพาเรนต์และใช้วิธีการของคลาสย่อย ฉันคิดว่ามันขึ้นอยู่กับการประกาศคลาสนั้น วิธีการ
ลองคิดดู:
จากการทดสอบที่ 3 เราจะแยกคุณลักษณะของคลาสย่อยได้อย่างไร - - - -