| นัท
: ถ้า overloaded methods หลายๆ
ตัวมี parameters จำนวนเท่ากัน แต่ประเภทต่างกันบ้าง
เวลาเราเรียกใช้แบบส่ง arguments ต่างๆ
ซึ่งมีประเภทไม่ตรงกับ parameters ของเมท็อดเหล่านี้แบบเป๊ะๆ
แล้วเขาจะเลือก methods ไหนให้ ?
ได้ลองดูบ้างบางกรณีที่แปลผ่าน
บางกรณีก็ฟ้องว่ากำกวม อยากรู้กฎการเลือกเมท็อดที่แน่นอน
1: public class A { 2: public static void main(String[] args) { 3: new A().g(1, 1, 1); 4: } 5: void g(int x, long y, int z) {System.out.println("1");} 6: void g(int x, double y, int z) {System.out.println("2");} 7: }
แบบนี้แปลผ่าน และเลือกเมท็อดแรก
1: public class A { 2: public static void main(String[] args) { 3: new A().g(1, 1, 1); 4: } 5: void g(int x, long y, int z) {System.out.println("1");} 6: void g(long x, int y, int z) {System.out.println("2");} 7: }
แบบบนนี้แปลไม่ผ่าน บ่นว่ากำกวม
พ่อ :
เปิดดู Java Language Specification
หัวข้อ 15.12.2.2
พบว่ามีใจความท่อนหนึ่งเขียนไว้อย่างนี้
"The Java programming language uses the rule that the most specific method
is chosen."
"The informal intuition is that one method declaration is
more specific than another if any invocation handled by the first method
could be passed on to the other one without a compile-time type error."
วิธีการเลือก method ที่จะเรียก จะนำ methods ทั้งหลายที่รับ arguments ต่างๆ
ที่ต้องการส่งได้ มาพิจารณาเพื่อเลือกอันที่ specific มากสุด
การพิจารณาว่าใคร specific
กว่าใครหรือไม่ กระทำดังนี้
ถ้า parameters ของ method
หนึ่งสามารถส่งไปให้ parameters ในอีก method หนึ่งได้หมด ถือได้ว่า method
แรก specific มากกว่า method หลัง
ตัวอย่างที่ 1
void g(int x, int y, byte z) {}
void g(int x, long y, int z) {}
void g(long x, int y, long z) {}
ถ้าต้องการเรียก g(1,1,1) จะตัด method แรกออกจากการพิจารณา เพราะรับ byte
ที่เหลือสองเมท็อด พบว่าเราไม่สามารถนำ parameters ของ method
ที่สองส่งให้ method ที่สาม (ติดตัวกลาง long y ส่งให้ int y
ไม่ได้)
และในทางกลับกัน เราก็ไม่สามารถนำ parameters ของ method ที่สามส่งให้
method ที่สอง (ติดตัวแรก และหลัง) แบบนี้การเรียกใช้ g(1,1,1) จะ compile
ไม่ผ่าน เพราะ g(1,1,1) ส่งให้ method ที่สองและสามได้ แต่ไม่มีตัวใด specific
กว่ากัน
ตัวอย่างที่ 2
void g(int x, long y, int z) {}
void g(int x, double y, int z) {}
ถ้าต้องการเรียก g(1,1,1) พบว่า method ทั้งสองรับได้
พิจารณาทั้งสอง methods นี้ จะพบว่าเราสามารถนำ parameters ของ method
แรก ส่งให้ method หลังได้หมด (ตัวแรกและตัวหลังเหมือนกัน ส่วนตัวกลาง long y
ส่งให้ double y ได้) แบบนี้การเรียกใช้ g(1,1,1) จะ compile ผ่าน และเลือก
method แรก เพราะ specific กว่า
นัท :
ขอกลับไปทดลองดูค่ะ
เกร็ดกาแฟ Copyright 2003
Somchai Prasitjutrakul |