2010-08-16 26 views
11

Tôi không thể hiểu tại sao mã này không biên dịch:nhiều lớp trong một tập tin duy nhất: modifier tin không được phép ở đây

class A { 
    public static void main(String[] args) { 
     System.out.println("hi"); 
    } 
} 

private class B { 
    int a; 
} 

Tôi đang tiết kiệm các nội dung trong một file có tên A.java - và tôi nhận được một lỗi:

modifier private not allowed here // where I have defined class B 

Điều này xảy ra khi tôi thử B là riêng tư và được bảo vệ. Ai đó có thể vui lòng giải thích cho tôi lý do đằng sau điều này?

Cảm ơn!

+0

Lớp bên trong có thể là riêng tư. –

+0

Không, nó dường như không phụ thuộc vào A – SlowAndSteady

Trả lời

13

Từ Java Language specification:

The access modifiers protected and private pertain only to member classes within a directly enclosing class declaration

Vì vậy, có, tư nhân và từ bổ nghĩa bảo vệ không được phép cho khai báo lớp cấp cao nhất.

Cấp cao nhất lớp học có thể công khai hoặc không, trong khi privateprotected không được phép. Nếu lớp được khai báo là public, thì nó có thể được gọi từ bất kỳ gói nào. Nếu không, nó chỉ có thể được gọi từ cùng một gói (không gian tên).

Lớp cấp cao nhất tư nhân sẽ không có ý nghĩa nhiều bởi vì nó không thể được giới thiệu từ bất kỳ lớp nào. Nó sẽ không sử dụng được theo định nghĩa. private là OK cho các lớp thành viên để làm cho một lớp tham chiếu đến chỉ có nó bao quanh lớp.

Lớp thành viên được bảo vệ có thể được tham chiếu từ (1) bất kỳ lớp nào của cùng một gói và từ (2) bất kỳ lớp con nào của lớp kèm theo. Lập bản đồ khái niệm này cho các lớp cấp cao là khó khăn. Trường hợp đầu tiên được bao phủ bởi lớp cấp cao nhất mà không có bộ sửa đổi truy cập. Trường hợp thứ hai không áp dụng cho các lớp cấp cao nhất, bởi vì không có lớp kèm theo hoặc một cái gì đó khác từ một gói khác với một mối quan hệ đặc biệt với lớp này (giống như một lớp con). Bởi vì điều này tôi nghĩ rằng, protected không được phép vì khái niệm cơ bản của nó không áp dụng cho các lớp cấp cao nhất.

+0

Cảm ơn Andreas, nhưng bạn có thể vui lòng cho tôi hiểu tại sao các nhà phát triển Java có thể áp đặt hạn chế này không? Tôi biết câu hỏi này nghe có vẻ vô lý, nhưng tôi tò mò. Cảm ơn ! – SlowAndSteady

+1

OK. Có logic cho riêng tư, nhưng những gì về bảo vệ ?? 'Được bảo vệ' chắc chắn cởi mở hơn so với thông số 'mặc định' - đã được cho phép! – SlowAndSteady

0

Chỉ không có công cụ sửa đổi riêng tư/được bảo vệ.

+0

Tôi muốn nói rằng tôi đã thử cả riêng và được bảo vệ riêng, nhưng nó không hoạt động trong cả hai trường hợp – SlowAndSteady

+0

Tôi chỉ đang thử nghiệm kiểm soát truy cập, tôi chỉ muốn biết lý do lỗi . – SlowAndSteady

0

B cần phải riêng tư đối với nội dung nào đó. Đặt nó trong định nghĩa của lớp A hoặc tạo một tệp khác, B.java và xác định nó ở đó, nhưng sau đó nó không thể là riêng tư.

+0

Có phải đó là một quy tắc trong Java để biến một lớp/biến riêng tư hoặc được bảo vệ thành "một cái gì đó"? Không, chúng tôi có các lớp/biến độc lập riêng tư hoặc được bảo vệ? – SlowAndSteady

+0

Tuyên bố của tôi trừu tượng hơn khái niệm. Vấn đề cơ bản là bạn đã khai báo một lớp khác trong tệp A.java. Có vẻ như bạn muốn đặt B ở chế độ riêng tư thành A hoặc trong 'cái gì đó'. Tuy nhiên, tuyên bố của bạn về chúng ta có thể có các lớp độc lập riêng tư hay được bảo vệ không thực sự có ý nghĩa bởi vì các công cụ sửa đổi chỉ có ngữ cảnh khi chúng liên quan đến một cái gì đó. – linuxuser27

2

Hãy B lồng nhau của A, như thế này:

class A { 
    public static void main(String[] args) { 
     System.out.println("hi"); 
    } 

    private class B { 
     int a; 
    } 
} 

Hoặc di chuyển B vào một tập tin riêng biệt. Ngoài ra bạn có thể gắn bó với cấp độ truy cập mặc định, cách này, lớp có thể được truy cập chỉ từ bên trong gói:

class A { 
    public static void main(String[] args) { 
     System.out.println("hi"); 
    } 
} 

class B { 
    int a; 
} 
+0

Tôi không muốn làm tổ hoặc chuyển sang tệp khác. Tôi chỉ muốn biết nguyên nhân của lỗi – SlowAndSteady

+0

Lỗi thực sự là hiển nhiên. Nếu bạn không làm điều đó lồng nhau hoặc tập tin riêng biệt lớp học sẽ không thể truy cập từ bất cứ nơi nào, vì nó là riêng tư. Bạn không thể làm cho nó công khai cũng được, gây ra java có một hạn chế của một lớp cấp công khai cho mỗi tập tin. –

+0

Nhưng những gì về bảo vệ? – SlowAndSteady

-1

Nếu bạn không sử dụng từ khóa nào cho lớp nó sẽ tin theo mặc định (có thể nhìn thấy chỉ trong tệp).

Chỉ có thể có một lớp công khai cho mỗi tệp .java, tất cả các tệp khác cần phải riêng tư. Vì vậy, lớp A có thể là công khai và lớp B không cần bất kỳ công cụ sửa đổi nào trong ví dụ của bạn. Tên lớp công khai phải khớp với tên tệp .java (ví dụ: A.java chỉ có thể chứa một lớp công khai có tên là "A").

+0

Điều này không chính xác. Lớp cấp cao nhất không có công cụ sửa đổi là * gói * riêng tư. Nó có thể được gọi từ bất kỳ lớp nào trong cùng một gói. –

-2

A.java không được chứa hai lớp.

+2

Có thể, miễn là chỉ có một là công khai (một tệp cung cấp cho tệp nguồn tên của nó) và tất cả các công khai khác (không thể sửa đổi truy cập, gói a.k.a), tệp nguồn có thể chứa nhiều lớp. –

+1

-1, xin lỗi đó không chính xác như Andrei giải thích. – djna

1

riêng tư và được bảo vệ là vô nghĩa khi được phép lên lớp/giao diện cấp cao nhất (không phải thành viên).

Chúng chỉ áp dụng cho các thành viên lớp có thể là biến, hằng số, hàm tạo, phương thức, lớp và giao diện.

Tại sao:

(1) tin: gì có thể là ý nghĩa/mục đích nếu chúng ta định nghĩa một lớp như tư nhân. Phạm vi của nó phải là riêng tư đối với một số khu vực. quyền truy cập mặc định đã là gói riêng tư. Và không ai muốn một lớp là tệp tin riêng tư, (Đoán lý do) nó có thể không phải là một thực hành lập trình tốt để cho phép bởi vì các ứng dụng java cuối cùng được tổ chức dưới dạng các gói, nhưng không phải về các tệp nguồn. Bất kỳ tệp nguồn nào phải là một phần của một số gói, vì vậy trong chế độ xem rộng/cuối cùng, mỗi lớp/giao diện là một phần của một số gói, không chỉ là một số tệp .java. Vì vậy, không áp dụng.

(2) được bảo vệ: Nếu nội dung nào đó được bảo vệ, nó chỉ có sẵn trong gói và chỉ cho các lớp con trong các gói khác. Để mở rộng một lớp trong một gói khác, nó sẽ có sẵn cho tất cả các lớp trong các gói khác, nhưng bảo vệ nói rằng lớp nên chỉ có sẵn cho các lớp mở rộng nó. Đó là một tình huống bế tắc. Vì vậy, không áp dụng.

Nguồn: Đọc và hiểu của tôi

+0

Miễn là nó không được công khai, một lớp có thể có tên khác với tên tệp của nó. Lớp học cũng có thể có phương pháp chính. Tệp lớp sẽ được tạo với tên lớp nhưng không phải với tên tệp nguồn. Tên lớp nên được sử dụng để thực thi nó. – Venkataswamy

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