2016-04-15 23 views
8
public class Test 
{ 
    static int i = 1; 

    static void m1() 
    { 
    } 
} 

class Test1 extends Test 
{ 
    int i = 1; //allowed 

    void m1()  // not allowed; Both are instance level, so why this difference? Both can be accessed with super keyword 
    { 
    } 
} 

Tại sao phương thức tĩnh không được ẩn với cùng một chữ ký, nhưng trường tĩnh được phép thực hiện việc này? Cả hai đều là cấp độ thể hiện, vậy tại sao chỉ có trường tĩnh được cho phép?Hỗ trợ thừa kế để ẩn phương thức và ẩn trường

+1

[Here's không phải là một câu trả lời rõ ràng, nhưng đó là đoán rằng lẩn trốn phương pháp tĩnh hoặc vica câu có thể dẫn đến sự nhầm lẫn] (http://stackoverflow.com/question/14602220/why-doesnt-java-allow-hide-static-methods-by-instance-methods) – SomeJavaGuy

Trả lời

8

m1() trong lớp Test là phương pháp static, trong khi m1() trong Test1 không tĩnh. Bây giờ tưởng tượng nếu điều này có thể đã được cho phép sau đó thực hiện sẽ được chọn bởi thời gian chạy khi bạn thực hiện dưới đây tuyên bố:

new Test1().m1(); 

Kể từ khi thể hiện của lớp con (Test1 trong trường hợp của bạn) có thể truy cập cũng truy cập phương pháp tĩnh từ lớp cha (từ Test). Đó là lý do tại sao nó không được phép.

Cho bạn câu hỏi tiếp theo tại sao biến có cùng tên được cho phép trong Test1: biến tĩnh của lớp cha không thể truy cập được từ phiên bản lớp con. Nói cách khác, trạng thái tĩnh của lớp cha được ẩn khỏi con. Đó là

Test1.i; // compilation error, can't access parent's static variable 

sẽ dẫn đến lỗi biên dịch. Và nếu bạn thử

new Test1().i; // will access Test1's i variable 

nó sẽ trỏ đến trạng thái của lớp con 'không phải của cha mẹ. Đó là lý do tại sao lớp con có thể có cùng tên.

Lưu ý: Nếui trong Test là không tĩnh, ngay cả trong trường hợp đó Test1 có thể có biến với tên i. Trong trường hợp này, i trong Test1 sẽ đổ bóng i trong Test.

EDIT

Từ Shahaan Syed của comment:

new Test1().i; tại sao được phép này là của tôi liên quan

Để đưa nhầm lẫn Shahaan Syed của nói cách khác: Tại sao

  • trong trường hợp thay đổi, lớp trẻ có thể có một biến không tĩnh trong khi tầng lớp phụ huynh có một biến tĩnh có cùng tên,
  • Mặt khác, lớp trẻ không thể có một không tĩnh phương thức khi lớp cha có phương thức tĩnh có cùng tên không?

Như Kevin Esche commented, tôi cũng nghĩ rằng Java sai lầm ở đâu đó bằng cách cho phép truy cập vào static phương pháp của lớp cha mẹ từ thể hiện của lớp con. Mặc dù nó không phải là một thực hành tốt và trình biên dịch tạo ra cảnh báo là tốt.

Dưới đây là một trích dẫn từ (JLS §8.3):

Trong khía cạnh này, cất giấu các lĩnh vực khác với ẩn của phương pháp (§8.4.8.3), vì không có sự khác biệt giữa vẽ tĩnh và phi các trường tĩnh trong trường ẩn trong khi phân biệt được vẽ giữa các phương thức tĩnh và không tĩnh trong phương thức ẩn.

Nhưng tôi không thể tìm thấy bất kỳ lý do nào đằng sau điều này trong JLS.

Tôi nghĩ rằng thay vì tạo cảnh báo, có lẽ đã có lỗi thời gian biên dịch. Điều đó đang truy cập cả hai trường staticstatic của lớp cha từ phiên bản lớp con, phải là lỗi trình biên dịch. Về mặt này, mọi thứ sẽ nhất quán và dễ hiểu. Nhưng một lần nữa nó chỉ là suy nghĩ của tôi.

Một câu hỏi thú vị trên cùng một dòng: Why isn't calling a static method by way of an instance an error for the Java compiler?

+4

Để thêm vào câu trả lời này, rất có khả năng điều này được thực hiện để tránh nhầm lẫn có gốc của nó trong một thiết kế ngôn ngữ xấu ở đây (beeing có thể gọi các phương thức tĩnh trên các cá thể đối tượng). – SomeJavaGuy

+0

@sudhir singh, nhưng tôi cũng đã nói cho Test1 mới(). I; tại sao điều này được cho phép là điểm liên quan của tôi. –

+2

@ShahaanSyed Bởi vì tại thời điểm này ngôn ngữ java được thiết kế kém. Đáng buồn thay đó là câu trả lời chính đáng duy nhất ở đây. – SomeJavaGuy

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