2015-11-19 17 views
31

Tôi cố gắng hiểu tại sao có sự khác biệt giữa khả năng truy cập của các thành viên lớp khi nói về các nhà xây dựng.Khả năng hiển thị của các nhà xây dựng tư nhân Java

Hãy xem xét ví dụ sau:

class A { 
    static class B { 
    private B(String s) {} 
    private void foo() {} 
    } 
    static class C extends B { 
    public C(String s) { 
     super(s); // call B(String), which is private, and obviously accessible 
    } 
    void bar() { 
     foo(); // compilation error (symbol unknown), as B.foo() is private 
    } 
    } 
} 

cá nhân các thành viên của A, như là tư nhân, không nên truy cập từ B. Đối với các trường và phương thức, đúng là như vậy, nhưng có vẻ như các hàm tạo không tuân theo cùng một quy tắc.

Từ JLS-8 (6.6.1. Determining Accessibility), chúng ta có thể đọc:

[...]

Một thành viên (lớp, giao diện, lĩnh vực, hoặc phương pháp) của một loại tài liệu tham khảo, hoặc một constructor của một kiểu lớp, có thể truy cập chỉ khi loại có thể truy cập và thành viên hoặc constructor được khai báo cho phép truy cập:

  • [...]

  • Nếu không, thành viên hoặc hàm tạo được khai báo private và quyền truy cập chỉ được phép nếu và chỉ khi nó xảy ra trong phần thân của lớp cấp cao nhất (§7.6) bao quanh khai báo của thành viên hoặc hàm tạo.

thể bất cứ ai giải thích cho tôi lý do tại sao các nhà xây dựng có thể truy cập từ C, ngay cả khi được tuyên bố private?

+1

Chỉ vì bạn có thể gọi siêu không có nghĩa là hàm tạo có thể truy cập – michaelsnowden

+2

Bất cứ ai có thể giải thích tại sao hàm tạo có thể truy cập từ C, ngay cả khi được khai báo riêng tư? -> Bởi vì cả hai B và C là lớp bên trong của A. Sẽ không làm việc nữa nếu bạn di chuyển B và C bên ngoài A. –

+3

@ JörnBuitink: Nếu đó là trường hợp, thì tại sao 'foo()' * không * có thể truy cập? Dường như có sự mâu thuẫn ở đây. –

Trả lời

25

Phương thức foo() là riêng tư, vì vậy bạn không kế thừa và không thể gọi trực tiếp từ lớp C.

Tuy nhiên, bạn có thể thấy phương pháp tư nhân và nhà xây dựng từ B kể từ khi tất cả mọi thứ được khai báo trong lớp chứa tương tự, và truy cập chúng với super, đó là lý do super() công trình. Trong cùng một cách, bạn có thể truy cập foo với super.foo().

Lưu ý rằng bạn có thể xác định lại phương thức foo mới trong C, nhưng phương pháp này sẽ không ghi đè B.foo().

+0

Cảm ơn rất nhiều câu trả lời của bạn WilQu & @benzonico. Nó có vẻ là lừa. Do đó tôi chấp nhận câu trả lời của bạn. –

3

Vì vậy, thủ thuật ở đây có thể là như sau:

bạn không thể truy cập foo bởi vì nó được khai báo là private vì vậy bạn không kế thừa nó trong C.

Tuy nhiên, như đã được ghi nhận trong ý kiến ​​bạn có thể truy cập super.foo();super đề cập đến loại được khai báo trong cùng một lớp cấp cao nhất (xem JLS 6.6.1 cho điều này).

Sau đó lừa là gọi super(s) có thể được xem như gọi super.<init>(s) mà kết thúc là trường hợp tương tự như super.foo()

-2

Foo() phương pháp là không thể truy cập trong lớp C, như foo() phương pháp là tư nhân và cá nhân phương pháp không thể được kế thừa vào lớp cơ sở.

Đối với các nhà thầu, các CONSTRUCTORS KHÔNG BAO GIỜ BAO GIỜ ĐƯỢC HẾT HẠN. Ngoài ra, tôi biên soạn mã này:

class Vehicle{ 
     int speed=50; 
     private Vehicle() 
     { 
      System.out.println("Private Vehicle constructor"); 
     } 
    } 
    public class Bike4 extends Vehicle{ 
     int speed=100; 
    Bike4() 
    { 
     super(); 
     System.out.println("Hi I n constructor"); 
    } 
    void display(){ 
    System.out.println(super.speed);//will print speed of Vehicle now 
    } 
    public static void main(String args[]){ 
    Bike4 b=new Bike4(); 
    b.display(); 

} 
} 

Và nhận Compile thời gian Lỗi: Xe() có quyền truy cập riêng trong xe siêu(); ^ Điều này cho thấy rõ ràng rằng một hàm tạo riêng tư không thể truy cập được bằng siêu. Nếu chúng ta có thể khởi tạo hoặc truy cập một hàm tạo riêng, thì đó là điểm tạo ra một hàm tạo riêng.

+0

Vui lòng xem các câu trả lời khác, câu trả lời của bạn không thực sự liên quan đến câu hỏi. – benzonico

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