CodeGym /หลักสูตร /จาวาคอร์ /พิมพ์หล่อ. การแปลงที่กว้างขึ้นและแคบลง

พิมพ์หล่อ. การแปลงที่กว้างขึ้นและแคบลง

จาวาคอร์
ระดับ, บทเรียน
มีอยู่

"สวัสดี Amigo! หัวข้อของบทเรียนวันนี้คือการแปลงประเภทกว้างและแคบลง คุณได้เรียนรู้เกี่ยวกับการขยายและแคบประเภทดั้งเดิมเมื่อนานมาแล้ว ในระดับ 10 วันนี้เราจะพูดถึงวิธีการทำงานของประเภทอ้างอิง เช่น ตัวอย่างของชั้นเรียน"

ในความเป็นจริงมันค่อนข้างง่าย ลองนึกภาพห่วงโซ่การสืบทอดของคลาส: คลาส, พาเรนต์ของมัน, พาเรนต์ของพาเรนต์ ฯลฯ ไปจนถึงคลาสอ็อบเจกต์ เนื่องจากคลาสประกอบด้วยเมธอดสมาชิกทั้งหมดของคลาสที่รับมา อินสแตนซ์ของคลาสสามารถบันทึกในตัวแปรที่มีประเภทเป็นของพาเรนต์ใด ๆ

นี่คือตัวอย่าง:

รหัส คำอธิบาย
class Animal
{
public void doAnimalActions();
}class Cat extends Animal
{
public void doCatActions();
}class Tiger extends Cat
{
public void doTigerActions();
}
ที่นี่เรามีประกาศสามประเภท: สัตว์ แมว และเสือ แมวสืบทอดสัตว์ และไทเกอร์ก็สืบทอดแคท
public static void main(String[] args)
{
Tiger tiger = new Tiger();
Cat cat = new Tiger();
Animal animal = new Tiger();
Object obj = new Tiger();
}
วัตถุ Tiger สามารถกำหนดให้กับตัวแปรที่มีประเภทเป็นของบรรพบุรุษตัวใดตัวหนึ่งได้เสมอ สำหรับคลาส Tiger ได้แก่ Cat, Animal และ Object

ทีนี้มาดูการแปลงที่กว้างขึ้นและแคบลง

หากการดำเนินการมอบหมายทำให้เราต้องเลื่อนระดับการสืบทอด (ไปยังคลาสออบเจกต์) เรากำลังจัดการกับการแปลงที่กว้างขึ้น (หรือที่เรียกว่าการอัปคาสติ้ง) หากเราเลื่อนห่วงโซ่ไปยังประเภทของอ็อบเจกต์ ก็จะเป็น Conversion ที่แคบลง (หรือที่เรียกว่า downcasting)

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

รหัส คำอธิบาย
public static void main(String[] args)
{
Object obj = new Tiger();
Animal animal = (Animal) obj;
Cat cat = (Cat) obj;
Tiger tiger = (Tiger) animal;
Tiger tiger2 = (Tiger) cat;
}
เมื่อจำกัดประเภท คุณต้องใช้ตัวดำเนินการแปลงประเภท กล่าวคือ เราทำการแปลงอย่างชัดเจน

สิ่งนี้ทำให้เครื่อง Java ตรวจสอบว่าวัตถุสืบทอดประเภทที่เราต้องการแปลงหรือไม่

นวัตกรรมขนาดเล็กนี้ทำให้จำนวนข้อผิดพลาดในการหล่อประเภทลดลงอย่างมาก และเพิ่มความเสถียรของโปรแกรม Java ได้อย่างมาก

รหัส คำอธิบาย
public static void main(String[] args)
{
Object obj = new Tiger();
if (obj instanceof Cat)
{
Cat cat = (Cat) obj;
cat.doCatActions();
}}
ยังดีกว่า ใช้  อินสแตนซ์ของการตรวจสอบ
public static void main(String[] args)
{
Animal animal = new Tiger();
doAllAction(animal);

Animal animal2 = new Cat();
doAllAction(animal2);

Animal animal3 = new Animal();
doAllAction(animal3);
}

public static void doAllAction(Animal animal)
{
if (animal instanceof Tiger)
{
Tiger tiger = (Tiger) animal;
tiger.doTigerActions();
}

if (animal instanceof Cat)
{
Cat cat = (Cat) animal;
cat.doCatActions();
}

animal.doAnimalActions();
}
และนี่คือเหตุผล ลองดูตัวอย่างทางด้านซ้าย

เรา (รหัสของเรา) ไม่รู้เสมอไปว่าเรากำลังทำงานกับวัตถุประเภทใด อาจเป็นวัตถุประเภทเดียวกับตัวแปร (สัตว์) หรือประเภทลูกหลาน (แมว เสือ)

พิจารณาวิธีการ doAllAction มันทำงานได้อย่างถูกต้อง โดยไม่คำนึงถึงประเภทของวัตถุที่ส่งผ่านเข้ามา

กล่าวอีกนัยหนึ่ง มันทำงานอย่างถูกต้องสำหรับสัตว์ทั้งสามประเภท: สัตว์ แมว และเสือ

public static void main(String[] args)
{
Cat cat = new Tiger();
Animal animal = cat;
Object obj = cat;
}
ที่นี่เรามีการดำเนินการมอบหมายสามรายการ ทั้งหมดนี้เป็นตัวอย่างของการแปลงที่กว้างขึ้น

ไม่จำเป็นต้องใช้ตัวดำเนินการประเภทคาสต์ที่นี่ เนื่องจากไม่จำเป็นต้องมีการตรวจสอบ การอ้างอิงออบเจกต์สามารถเก็บไว้ในตัวแปรที่มีประเภทเป็นบรรพบุรุษของมันได้เสมอ

"โอ้ ตัวอย่างที่สองจากตัวอย่างสุดท้ายทำให้ทุกอย่างชัดเจน: เหตุใดจึงต้องมีการตรวจสอบ และเหตุใดจึงต้องมีการคัดเลือกประเภท"

"ฉันหวังอย่างนั้น ฉันอยากให้คุณสนใจข้อเท็จจริงนี้:"

สิ่งนี้ไม่ได้ทำให้วัตถุเปลี่ยนแปลง แต่อย่างใด! สิ่งเดียวที่เปลี่ยนแปลงคือจำนวนเมธอดที่สามารถเรียกใช้กับตัวแปรอ้างอิงเฉพาะได้

ตัวอย่างเช่น ตัวแปร Cat ให้คุณเรียกใช้เมธอด doAnimalActions และ doCatActions มันไม่รู้อะไรเลยเกี่ยวกับเมธอด doTigerActions แม้ว่าจะชี้ไปที่วัตถุ Tiger ก็ตาม

"ใช่ ฉันเข้าใจแล้ว มันง่ายกว่าที่ฉันคิดไว้ซะอีก"

4
งาน
จาวาคอร์, ระดับ, บทเรียน
ล็อค
Code entry
Your attention, please! Now recruiting code entry personnel for CodeGym. Turn up your focus, let your fingers relax, read the code, and then... type it into the appropriate box. Code entry is far from a useless exercise, though it might seem so at first glance: it allows a beginner to get used to and remember syntax (modern IDEs seldom make this possible).
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION