เหตุใดจึงไม่สามารถโอเวอร์โหลดฟังก์ชันได้เพียงแค่เปลี่ยนประเภทการส่งคืน จะมีการเปลี่ยนแปลงใน Java เวอร์ชันอนาคตหรือไม่?
อย่างไรก็ตามสำหรับการอ้างอิงสิ่งนี้เป็นไปได้ใน C ++ หรือไม่?
เหตุใดจึงไม่สามารถโอเวอร์โหลดฟังก์ชันได้เพียงแค่เปลี่ยนประเภทการส่งคืน จะมีการเปลี่ยนแปลงใน Java เวอร์ชันอนาคตหรือไม่?
อย่างไรก็ตามสำหรับการอ้างอิงสิ่งนี้เป็นไปได้ใน C ++ หรือไม่?
คำตอบ:
คุณไม่สามารถทำได้ใน Java และคุณไม่สามารถทำได้ใน C ++ เหตุผลก็คือค่าส่งคืนเพียงอย่างเดียวไม่เพียงพอสำหรับคอมไพเลอร์ในการคิดว่าจะเรียกใช้ฟังก์ชันใด:
public int foo() {...}
public float foo() {..}
...
foo(); // which one?
float
double
foo();
ไม่มีประเภทการส่งคืนจะมีความคลุมเครือไม่จำเป็นต้องมีเหตุผลที่จะไม่อนุญาตให้เป็นแบบโอเวอร์โหลด มีข้อโต้แย้งที่อาจทำให้เกิดความไม่ชัดเจน (เช่นfoo(null);
) แต่นั่นไม่ได้ทำให้โอเวอร์โหลดโดยเนื้อแท้ไม่ถูกต้อง
เหตุผลก็คือการโอเวอร์โหลดใน Java จะได้รับอนุญาตสำหรับเมธอดที่มีลายเซ็นต่างกันเท่านั้น
ชนิดการส่งคืนไม่ได้เป็นส่วนหนึ่งของลายเซ็นเมธอดดังนั้นจึงไม่สามารถใช้เพื่อแยกแยะโอเวอร์โหลด
ดูการกำหนดวิธีการจากบทช่วยสอน Java
calculateAnswer(double, int, double, double)
" ดูว่าไม่รวมประเภทการคืนสินค้า @konmik
ก่อน Java 5.0 เมื่อคุณแทนที่เมธอดทั้งพารามิเตอร์และประเภทการส่งคืนจะต้องตรงกันทุกประการ ใน Java 5.0 จะแนะนำสิ่งอำนวยความสะดวกใหม่ที่เรียกว่าประเภทการส่งคืนโควาเรียน คุณสามารถแทนที่เมธอดที่มีลายเซ็นเดียวกัน แต่ส่งคืนคลาสย่อยของอ็อบเจ็กต์ที่ส่งคืน กล่าวอีกนัยหนึ่งเมธอดในคลาสย่อยสามารถส่งคืนอ็อบเจ็กต์ที่มีประเภทเป็นคลาสย่อยของประเภทที่ส่งคืนโดยเมธอดที่มีลายเซ็นเดียวกันในซูเปอร์คลาส
Overloaded
วิธีการใน java อาจมีประเภทการส่งคืนที่แตกต่างกันเนื่องจากอาร์กิวเมนต์นั้นแตกต่างกันด้วย
ตรวจสอบโค้ดตัวอย่าง
public class B {
public String greet() {
return "Hello";
}
//This will work
public StringBuilder greet(String name) {
return new StringBuilder("Hello " + name);
}
//This will not work
//Error: Duplicate method greet() in type B
public StringBuilder greet() {
return new StringBuilder("Hello Tarzan");
}
}
คอมไพลเลอร์ไม่พิจารณาประเภทการส่งคืนเมื่อแยกเมธอดดังนั้นคุณจึงไม่สามารถประกาศสองวิธีด้วยลายเซ็นเดียวกันแม้ว่าจะมีชนิดการส่งคืนที่แตกต่างกันก็ตาม
ประเภทการส่งคืนไม่สำคัญในขณะที่ใช้วิธีการมากเกินไป เราต้องมั่นใจว่าไม่มีความคลุมเครือ!
วิธีเดียวที่ Java สามารถทราบว่าจะเรียกใช้เมธอดใดคือการแยกประเภทของรายการอาร์กิวเมนต์ หากคอมไพลเลอร์อนุญาตสองวิธีที่มีชื่อเดียวกันและประเภทอาร์กิวเมนต์เดียวกันจะไม่มีทางระบุได้ว่าควรเรียกใช้วิธีใด
คอมไพลเลอร์ไม่พิจารณาประเภทการส่งคืนเมื่อแยกเมธอดดังนั้นคุณจึงไม่สามารถประกาศสองวิธีด้วยลายเซ็นเดียวกันแม้ว่าจะมีชนิดการส่งคืนที่แตกต่างกันก็ตาม
หากคุณทราบถึงการเรียกใช้ฟังก์ชันคุณจะทราบว่าเมื่อเราเรียกใช้ฟังก์ชันส่วนนิยามจะดำเนินการและในที่สุดเราต้องการคำสั่ง return ดังนั้นเราจึงสามารถพูดได้ว่า return เกิดขึ้นหลังจากคำจำกัดความทั้งหมดของฟังก์ชันนั่นคือเหตุผลว่าทำไมถ้ามีสองหรือ ฟังก์ชั่นอื่น ๆ ที่มีชื่อเดียวกันและประเภทเดียวกันและไม่มี ของอาร์กิวเมนต์ในเวลาที่เรียกว่าคอมไพเลอร์จะรู้ได้อย่างไรว่าจะเรียกตัวใดเนื่องจากชื่อฟังก์ชันและพารามิเตอร์เหมือนกัน ในช่วงเวลาของการโทรประการแรกโฟกัสทั้งหมดจะอยู่ที่อาร์กิวเมนต์และชื่อฟังก์ชันและหลังจากเสร็จสิ้นการกำหนดฟังก์ชันในที่สุดเราก็จัดการกับคำสั่ง return
Compile Time Error ดีกว่า Run Time Error ดังนั้นคอมไพเลอร์ java จึงแสดงข้อผิดพลาดเวลาคอมไพเลอร์หากคุณประกาศวิธีการเดียวกันที่มีพารามิเตอร์เดียวกัน
ไม่มีทางเป็นไปได้จริงๆที่คุณสามารถโอเวอร์โหลดได้โดยไม่มีอาร์กิวเมนต์หรือประเภทข้อมูลของอาร์กิวเมนต์