2010-02-17 39 views
9

cố gắng quá tải java.lang.Math.sqrt phương pháp tĩnh cho int loại:quá tải của Math.sqrt: phương pháp quá tải dường như để che giấu bản gốc một

import static java.lang.Math.sqrt; 

class Test 
{ 
    private static double sqrt(int n) 
    { 
     return sqrt(1.0 * n); 
    } 

    public static void main(String[] args) 
    { 
     System.out.println(sqrt(1)); 
    } 
} 

lỗi lẻ phát sinh:

Test.java:7: sqrt(int) in Test cannot be applied to (double) 
       return sqrt(1.0 * n); 
        ^
1 error 

Nhưng khi rõ ràng tham chiếu phương thức java.lang.Math.sqrt tất cả đều tốt:

class Test 
{ 
    private static double sqrt(int n) 
    { 
     return Math.sqrt(1.0 * n); 
    } 

    public static void main(String[] args) 
    { 
     System.out.println(sqrt(1)); 
    } 
} 

Trình biên dịch được sử dụng là tiêu chuẩn javac, phiên bản 1.6.0_16.

Vì vậy, câu hỏi là:

  1. Tại sao là trình biên dịch không thể giải quyết quá tải trong trường hợp đầu tiên?
  2. Hành vi này được chỉ định trong thông số ngôn ngữ java ở đâu?

Xin cảm ơn trước.

+0

Lỗi là gì? – Pace

+1

Nói đúng ra bạn không quá tải bất kỳ phương pháp nào ở đây. –

Trả lời

13

Bạn chỉ có thể quá tải phương pháp trong cùng một lớp. I E. nếu bạn nhập một phương thức tĩnh của một lớp khác và sau đó xác định phương thức của riêng bạn có cùng tên, sẽ không có độ phân giải quá tải. Phiên bản đã nhập của phương thức sẽ đơn giản bị bỏ qua.

Về nơi hành vi này được quy định: Các đặc điểm kỹ thuật ngôn ngữ định nghĩa quá tải like this:

Nếu hai phương pháp của một lớp (cho dù cả hai tuyên bố trong cùng một lớp, hoặc cả hai được thừa kế bởi một lớp, hoặc một tuyên bố và một thừa kế) có cùng tên nhưng chữ ký không ghi đè tương đương, sau đó tên phương thức được gọi là quá tải.

Lưu ý rằng nó nói "hai phương pháp của một lớp". Vì vậy, các phương thức được nhập từ một lớp khác đơn giản là không được xem xét.

Vì vậy, kể từ khi định nghĩa của bạn không phải là một tình trạng quá tải của Math.sqrt, nó bóng tối nó theo section 6.3.1 of the definition:

Tờ khai d của một phương thức có tên n bóng tối tờ khai của bất kỳ phương pháp khác có tên n có trong một phạm vi bao quanh tại điểm mà d xảy ra trong phạm vi của d.

+0

Đó là câu trả lời! –

+0

Hành vi này được mô tả trong http://java.sun.com/docs/books/tutorial/java/IandI/override.html, trong phần về phương pháp lớp học. – tonio

+1

@tonio: Liên kết của bạn là về ghi đè so với ẩn, thay vì quá tải so với bóng tối, đây là vấn đề ở đây. – sepp2k

1

Vâng, sqrt(int) in Test cannot be applied to (double)

Đổi tên chức năng của bạn với tên khác, nếu bạn muốn gọi Math.sqrt:

private static double mysqrt(int n) 
{ 
    return sqrt(1.0 * n); 
} 
+0

Chỉ đơn giản là bỏ qua nhập tĩnh và sử dụng 'Math.sqrt()'. –

0

Trong lần gọi đầu tiên, phương thức được gọi là phương thức mà bạn đã trả về, kỳ vọng int là thông số của nó nhưng bạn đang gửi gấp đôi tham số đó. do đó, nó cung cấp cho một lỗi trình biên dịch.

Nhưng với cuộc gọi thứ hai bạn đang đề cập đến Math.sqrt() hoạt động tốt.

+0

lý do tại sao cấp dưới? ngữ pháp? – redcayuga

2

Bạn không thực sự quá tải. Mọi thứ đang bị treo trên một sự mơ hồ; trình biên dịch thấy return sqrt(1.0 * n);, nó giả định bạn đang nói về hàm sqrt(int) trong lớp Test, không phải là một trong lang.Math. Đây là hành vi thích hợp hơn; sau khi tất cả, bạn có thể không muốn phải chỉ định class.method mỗi khi bạn đang cố gắng gọi một chức năng thành viên. Và trình biên dịch không giải quyết được vì trong tình huống cụ thể của bạn, nó giả định bạn đã mắc lỗi và không nhận ra bạn định gọi số sqrt trong lang.Math.

3

Điều đó khá bình thường. Bằng cách viết mã này, bạn không quá tải phương thức Math.sqrt theo bất kỳ cách nào, bạn chỉ cần xác định một đối số là Test.sqrt(int).

Sau đó, có câu hỏi về thông báo lỗi của bạn.

Khi xác định phương pháp Test.sqrt, bạn quá tải (trong lớp này) nhập tĩnh bạn đã thực hiện.

Vì vậy, khi gọi sqrt (1.0 * n), trình biên dịch xem xét bạn thử gọi Test.sqrt (int) với một double, swhich rõ ràng là không thể.

Các vấn đề liên quan