Quá tải với kiểu trả về khác nhau trong Java?


104

Tại sao không thể quá tải một hàm chỉ bằng cách thay đổi kiểu trả về? Điều đó sẽ thay đổi trong một phiên bản Java trong tương lai?

Nhân tiện, chỉ để tham khảo, điều này có khả thi trong C ++ không?


1
có thể trùng lặp của Nạp chồng hàm theo kiểu trả về?
KNU

KNU, ​​câu trả lời khác khác ở chỗ nó hỏi câu hỏi nói chung, các thuật ngữ cụ thể không phải ngôn ngữ. Cũng thú vị là câu trả lời được chấp nhận của câu hỏi khác đi xa hơn bằng cách chỉ định rằng Java JVM cho phép nó được thực hiện với thao tác bên trong.
J Woodchuck

Câu trả lời:


157

Bạn không thể làm điều đó trong Java và bạn không thể làm điều đó trong C ++. Lý do là chỉ giá trị trả về là không đủ để trình biên dịch tìm ra hàm nào cần gọi:

public int foo() {...}
public float foo() {..}

...
foo(); // which one?

3
Tôi luôn nghĩ rằng nếu chúng ta làm điều gì đó như int i = foo () hoặc float f = foo () thì nó sẽ biết cái nào, nhưng nếu câu lệnh chỉ là hàm mà trình biên dịch sẽ không biết. Tôi hiểu rồi. Cảm ơn.
nunos 13/03/10

7
@nunos ngay cả khi nó là float f = foo (), trình biên dịch sẽ không thể tìm ra nó bởi vì cả một int sẽ là đầu vào hợp lệ cho một float. So sánh float f = 7; (7 là float hay int?)
NomeN

5
@NomeN Nhưng tuyên bố của bạn cho thấy rằng func (int i) và func (float i) sẽ không thể phân biệt được đối với trình biên dịch - và tất cả chúng ta đều biết điều này không đúng. Lý do thực sự được đưa ra bởi Oded (xem câu trả lời tiếp theo) - đó là về chữ ký của phương pháp. Và, btw. 7 chắc chắn là số nguyên trong khi 7,0 hoặc 7f là float ;-)
Ta Sas

7
7.0 không phải float, nó là double.
fredoverflow

3
Thực tế là foo();không có kiểu trả về sẽ không rõ ràng không nhất thiết là lý do để không cho phép nó như một quá tải. Có những đối số có thể gây ra sự mơ hồ (ví dụ foo(null);), nhưng điều đó không làm cho quá tải vốn không hợp lệ.
shmosel

48

Lý do là các quá tải trong Java chỉ được phép đối với các phương thức có các chữ ký khác nhau .

Kiểu trả về không phải là một phần của chữ ký phương thức, do đó không thể được sử dụng để phân biệt quá tải.

Xem Định nghĩa các phương pháp từ các hướng dẫn Java.


4
Nhưng tại sao kiểu trả về không phải là một phần của chữ ký
andho

51
ôi "chỉ vì"! Tôi hiểu rồi.
andho

3
Kiểu trả về LÀ một phần của chữ ký phương thức. Chỉ cần xem xét việc tháo gỡ lớp.
konmik

2
Nó thực sự không phải là @konmik - không phải bởi các quy tắc nạp chồng phương thức. Thử nó. Tên phương thức giống nhau, kiểu tham số giống nhau theo cùng thứ tự, kiểu trả về khác nhau. Sẽ không biên dịch.
Oded

3
Có, vì kiểu trả về không phải là một phần của chữ ký . Chữ ký là - tên của phương thức + các loại và thứ tự của tham số của nó. Đọc liên kết tôi đã cung cấp trong câu trả lời của mình: "Chữ ký của phương thức được khai báo ở trên là: calculateAnswer(double, int, double, double)". Thấy rằng loại trả lại không được bao gồm, @konmik.
Oded

22

Trước Java 5.0, khi bạn ghi đè một phương thức, cả tham số và kiểu trả về phải khớp chính xác. Trong Java 5.0, nó giới thiệu một cơ sở mới được gọi là kiểu trả về hiệp phương sai. Bạn có thể ghi đè một phương thức có cùng chữ ký nhưng trả về một lớp con của đối tượng được trả về. Nói cách khác, một phương thức trong lớp con có thể trả về một đối tượng có kiểu là một lớp con của kiểu được phương thức trả về cùng một chữ ký trong lớp cha.


3
Tôi đã bối rối khi lần đầu tiên nhìn thấy điều này. Cảm ơn đã giải thích tại sao điều này là có thể!
Dylan Knowles

2
quá tải và ghi đè là khác nhau. Quá tải không (nhất thiết) liên quan đến thừa kế
senseiwu

3
Câu trả lời này nghe có vẻ gây hiểu lầm cho một người mới sử dụng Java, bởi vì nó không liên quan đến việc quá tải , nó đang ghi đè - hoàn toàn khác.
azizbekian

4

Overloaded các phương thức trong java có thể có các kiểu trả về khác nhau do đối số cũng khác nhau.

Kiểm tra mã mẫu.

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");
    }

}

về cơ bản là kiểu trả về không được đưa vào tính toán, chỉ có các đối số, buồn nhưng là sự thật
Alexander Mills

1

Trình biên dịch không xem xét kiểu trả về khi phân biệt các phương thức, vì vậy bạn không thể khai báo hai phương thức với cùng một chữ ký ngay cả khi chúng có kiểu trả về khác nhau.


1

Kiểu trả về không quan trọng khi nạp chồng một phương thức. Chúng tôi chỉ cần đảm bảo không có sự mơ hồ!

Cách duy nhất Java có thể biết phương thức nào cần gọi là phân biệt các kiểu của danh sách đối số. Nếu trình biên dịch cho phép hai phương thức có cùng tên và cùng kiểu đối số, sẽ không có cách nào để xác định phương thức nào nó sẽ gọi.


0

Trình biên dịch không xem xét kiểu trả về khi phân biệt các phương thức, vì vậy bạn không thể khai báo hai phương thức với cùng một chữ ký ngay cả khi chúng có kiểu trả về khác nhau.

Nếu bạn biết về việc thực thi hàm thì bạn sẽ biết rằng khi chúng ta gọi một hàm, phần định nghĩa sẽ thực thi và cuối cùng chúng ta yêu cầu câu lệnh trả về, do đó chúng ta có thể nói rằng trả về đến sau toàn bộ định nghĩa của hàm, đó là lý do tại sao nếu có hai hoặc nhiều chức năng cùng tên và cùng loại và không. của đối số thì tại thời điểm gọi trình biên dịch sẽ biết cái nào sẽ được gọi, vì tên hàm và các tham số giống nhau. Tại thời điểm gọi trước hết mọi sự tập trung sẽ là đối số và tên hàm và sau khi hoàn thành định nghĩa hàm cuối cùng chúng ta xử lý với câu lệnh return.

Lỗi thời gian biên dịch tốt hơn Lỗi thời gian chạy. Vì vậy, trình biên dịch java hiển thị lỗi thời gian trình biên dịch nếu bạn khai báo cùng một phương thức có các tham số giống nhau.


Điều này khác với câu trả lời được chấp nhận như thế nào? (Cũng là lý do nó là một lỗi thời gian biên dịch là bởi vì trình biên dịch không thể tìm ra phương pháp để gọi, vậy làm thế nào là nó phải tạo ra các mã thực thi đúng đắn)
UnholySheep

-2

không, không thực sự có thể theo cách đó bạn chỉ có thể quá tải bởi không có đối số hoặc kiểu dữ liệu của đối số

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.