"สวัสดี Amigo! เมื่อสองสามวันก่อนฉันบอกคุณเกี่ยวกับวิธีการโอเวอร์โหลด คุณเข้าใจทุกอย่างไหม"
"ใช่ ฉันจำได้ แต่ละเมธอดของคลาสต้องไม่ซ้ำกัน เมธอดของสมาชิกจะไม่ซ้ำกันถ้าคลาสนั้นไม่มีเมธอดอื่นที่มีชื่อและประเภทพารามิเตอร์เหมือนกัน (และลำดับของพารามิเตอร์มีความสำคัญ)"
"ดีมาก! ฉันเห็นว่าคุณเรียนรู้บทเรียนนั้นได้ดี วันนี้ฉันอยากจะเพิ่มพูนความรู้ของคุณในหัวข้อนี้สักหน่อย คุณคิดว่าแต่ละกรณีจะเรียกว่าวิธีใด"
class Cat
{
public static void print(int n)
{
System.out.println(n);
}
public static void print(short n)
{
System.out.println(n);
}
public static void print(Integer n)
{
System.out.println(n);
}
public static void print(String s)
{
System.out.println(s);
}
public static void main(String[] args)
{
Cat.print(1);
Cat.print((byte)1);
Cat.print("1");
Cat.print(null);
}
}
"มันยากที่จะพูด."
"ในกรณีแรก 1 คือintเรามีการจับคู่ 100% กับวิธีการที่ใช้ int การพิมพ์โมฆะครั้งแรก (int n)จะถูกเรียก
ในกรณีที่สอง เราไม่มีเมธอดที่ใช้หน่วยเป็นไบต์ แต่มีสองวิธีที่ใช้เวลาสั้น ๆ และ int ตามกฎการขยายประเภท ไบต์จะถูกขยายเป็น short ก่อน แล้วจึงขยายเป็น int ดังนั้นคำตัดสินจึงเป็นโมฆะพิมพ์ (สั้น n) จะถูกเรียก
ในกรณีที่สาม เรามีการจับคู่ 100% กับเมธอดที่ใช้สตริง การพิมพ์เป็นโมฆะ (String s) จะถูกเรียกใช้เมธอด
กรณีที่สี่คลุมเครือ null ไม่มีประเภทเฉพาะ คอมไพเลอ ร์จะปฏิเสธที่จะคอมไพล์โค้ดนี้ ในกรณีนี้ เราจำเป็นต้องเขียนCat.print((Integer)null)เพื่อเรียกเมธอดที่สาม และCat.print((String)null)เพื่อเรียกเมธอดที่สี่"
"นั่นเป็นข้อมูลที่ดีมาก ขอบคุณ"
"ฉันต้องการชี้ให้เห็นว่าเมื่อกำหนดวิธีการเรียกที่ถูกต้อง ประเภทจะขยายได้เท่านั้น ไม่สามารถจำกัดให้แคบลงได้ ลองพิจารณาตัวอย่างนี้:"
class Cat
{
public static void print(short n)
{
System.out.println(n);
}
public static void print(Integer n)
{
System.out.println(n);
}
public static void main(String[] args)
{
Cat.print((byte)1);
Cat.print(1);
}
}
ในกรณีแรก ประเภทไบต์จะถูกขยายเป็นแบบสั้น และจะเรียกเมธอดแรกว่า: void print(short n) .
ในกรณีที่สอง จะมีการแปลงการขยายโดยปริยายจาก int เป็น Integer จากนั้นจะเรียกเมธอดที่สอง: void print(Integer n) .
"ฉันไม่ได้คาดหวังอย่างนั้น"
"ไม่ นี่คือเซอร์ไพรส์ที่แท้จริง:"
รหัสจาวา | คำอธิบาย |
---|---|
|
ในกรณีแรก int จะถูกขยายเป็นจำนวนเต็ม เนื่องจากไม่มีวิธีการสำหรับ Integer วิธีที่เหมาะสมที่สุด (และวิธีที่ถูกเรียก) คือvoid print(Object o)
ในกรณีที่สอง จะไม่มีข้อผิดพลาดในการคอมไพล์และvoid print(String s)จะถูกเรียก ซึ่งค่อนข้างไม่ชัดเจน |
"Amigo ฉันหวังว่าคุณจะเข้าใจว่าในกรณีเช่นนี้ เป็นการดีที่สุดที่จะระบุตัวดำเนินการประเภทการแคสต์ (เช่นเดียวกับที่เราทำกับ «(byte)») เพื่อจะได้ทราบอย่างแน่ชัดว่าเมธอดใดจะถูกเรียกใช้"
"ฉันไม่เคยคาดคิดมาก่อนว่าปัญหาจะมาจากวิธีการโอเวอร์โหลด แต่แล้วคุณก็เข้ามา ขอบคุณ Rishi ฉันจะคอยระวังในประเด็นนี้"