"สวัสดี Amigo! หัวข้อของบทเรียนวันนี้คือการแปลงประเภทกว้างและแคบลง คุณได้เรียนรู้เกี่ยวกับการขยายและแคบประเภทดั้งเดิมเมื่อนานมาแล้ว ในระดับ 10 วันนี้เราจะพูดถึงวิธีการทำงานของประเภทอ้างอิง เช่น ตัวอย่างของชั้นเรียน"
ในความเป็นจริงมันค่อนข้างง่าย ลองนึกภาพห่วงโซ่การสืบทอดของคลาส: คลาส, พาเรนต์ของมัน, พาเรนต์ของพาเรนต์ ฯลฯ ไปจนถึงคลาสอ็อบเจกต์ เนื่องจากคลาสประกอบด้วยเมธอดสมาชิกทั้งหมดของคลาสที่รับมา อินสแตนซ์ของคลาสสามารถบันทึกในตัวแปรที่มีประเภทเป็นของพาเรนต์ใด ๆ
นี่คือตัวอย่าง:
รหัส | คำอธิบาย |
---|---|
|
ที่นี่เรามีประกาศสามประเภท: สัตว์ แมว และเสือ แมวสืบทอดสัตว์ และไทเกอร์ก็สืบทอดแคท |
|
วัตถุ Tiger สามารถกำหนดให้กับตัวแปรที่มีประเภทเป็นของบรรพบุรุษตัวใดตัวหนึ่งได้เสมอ สำหรับคลาส Tiger ได้แก่ Cat, Animal และ Object |
ทีนี้มาดูการแปลงที่กว้างขึ้นและแคบลง
หากการดำเนินการมอบหมายทำให้เราต้องเลื่อนระดับการสืบทอด (ไปยังคลาสออบเจกต์) เรากำลังจัดการกับการแปลงที่กว้างขึ้น (หรือที่เรียกว่าการอัปคาสติ้ง) หากเราเลื่อนห่วงโซ่ไปยังประเภทของอ็อบเจกต์ ก็จะเป็น Conversion ที่แคบลง (หรือที่เรียกว่า downcasting)
การย้ายห่วงโซ่การสืบทอดขึ้นไปเรียกว่าการขยับขยาย เนื่องจากจะนำไปสู่ประเภททั่วไปมากขึ้น อย่างไรก็ตาม ในการทำเช่นนั้น เราสูญเสียความสามารถในการเรียกใช้เมธอดที่เพิ่มเข้ามาในคลาสผ่านการสืบทอด
รหัส | คำอธิบาย |
---|---|
|
เมื่อจำกัดประเภท คุณต้องใช้ตัวดำเนินการแปลงประเภท กล่าวคือ เราทำการแปลงอย่างชัดเจน
สิ่งนี้ทำให้เครื่อง Java ตรวจสอบว่าวัตถุสืบทอดประเภทที่เราต้องการแปลงหรือไม่ นวัตกรรมขนาดเล็กนี้ทำให้จำนวนข้อผิดพลาดในการหล่อประเภทลดลงอย่างมาก และเพิ่มความเสถียรของโปรแกรม Java ได้อย่างมาก |
รหัส | คำอธิบาย |
---|---|
|
ยังดีกว่า ใช้ อินสแตนซ์ของการตรวจสอบ |
|
และนี่คือเหตุผล ลองดูตัวอย่างทางด้านซ้าย
เรา (รหัสของเรา) ไม่รู้เสมอไปว่าเรากำลังทำงานกับวัตถุประเภทใด อาจเป็นวัตถุประเภทเดียวกับตัวแปร (สัตว์) หรือประเภทลูกหลาน (แมว เสือ) พิจารณาวิธีการ doAllAction มันทำงานได้อย่างถูกต้อง โดยไม่คำนึงถึงประเภทของวัตถุที่ส่งผ่านเข้ามา กล่าวอีกนัยหนึ่ง มันทำงานอย่างถูกต้องสำหรับสัตว์ทั้งสามประเภท: สัตว์ แมว และเสือ |
|
ที่นี่เรามีการดำเนินการมอบหมายสามรายการ ทั้งหมดนี้เป็นตัวอย่างของการแปลงที่กว้างขึ้น
ไม่จำเป็นต้องใช้ตัวดำเนินการประเภทคาสต์ที่นี่ เนื่องจากไม่จำเป็นต้องมีการตรวจสอบ การอ้างอิงออบเจกต์สามารถเก็บไว้ในตัวแปรที่มีประเภทเป็นบรรพบุรุษของมันได้เสมอ |
"โอ้ ตัวอย่างที่สองจากตัวอย่างสุดท้ายทำให้ทุกอย่างชัดเจน: เหตุใดจึงต้องมีการตรวจสอบ และเหตุใดจึงต้องมีการคัดเลือกประเภท"
"ฉันหวังอย่างนั้น ฉันอยากให้คุณสนใจข้อเท็จจริงนี้:"
สิ่งนี้ไม่ได้ทำให้วัตถุเปลี่ยนแปลง แต่อย่างใด! สิ่งเดียวที่เปลี่ยนแปลงคือจำนวนเมธอดที่สามารถเรียกใช้กับตัวแปรอ้างอิงเฉพาะได้
ตัวอย่างเช่น ตัวแปร Cat ให้คุณเรียกใช้เมธอด doAnimalActions และ doCatActions มันไม่รู้อะไรเลยเกี่ยวกับเมธอด doTigerActions แม้ว่าจะชี้ไปที่วัตถุ Tiger ก็ตาม
"ใช่ ฉันเข้าใจแล้ว มันง่ายกว่าที่ฉันคิดไว้ซะอีก"
GO TO FULL VERSION