2011-08-23 37 views
10

Được rồi, tôi biết đó là quy tắc:Tại sao giao diện chỉ có thể được khai báo trong lớp cấp cao nhất?

Theo JLS: 8.1.3 Lớp Nội và Instances Kèm theo, bên trong lớp chưa được công bố initializers tĩnh hoặc giao diện thành viên. Các lớp bên trong có thể không khai báo thành viên tĩnh, trừ khi chúng là trường hằng số biên dịch.

Theo 8.5.2 Static Thành viên Loại khai báo, "giao diện Thành viên luôn ngầm tĩnh. Nó được cho phép nhưng không bắt buộc cho tuyên bố một giao diện thành viên một cách rõ ràng danh sách các tĩnh modifier". Họ luôn là cấp cao nhất, không phải bên trong.

Tôi tự hỏi tại sao. Điều gì có thể xảy ra nếu chúng ta được phép khai báo giao diện trong một lớp bên trong? Liệu lớp bên trong có trở thành lớp cấp cao nhất không nếu tôi đặt nó vào một tệp lớp khác?

Trả lời

7

Sẽ không lớp bên trong trở thành lớp cấp cao nhất nếu tôi đặt nó vào một tệp Lớp khác?

Không, nó vẫn là một lớp bên trong, tên tệp cho biết (IIRC là OuterClass$InnerClass.class).

Các lớp bên trong có quyền truy cập vào thuộc tính của lớp bên ngoài, tức là chúng phụ thuộc vào cá thể lớp bên ngoài của chúng. Với giao diện bạn không thể làm điều này. Hãy nghĩ về một lớp hoàn toàn không liên quan mà phải được tạo ra bởi cá thể lớp bên ngoài tương ứng. Làm thế nào có thể được thực hiện nếu lớp bên ngoài không biết ai thực hiện giao diện đó?

Những gì bạn có thể làm là tuyên bố giao diện tĩnh trong lớp bên ngoài của bạn, do đó chỉ sử dụng bên ngoài như một không gian tên:

public class OuterClass { 
    public static interface InnerInterface { //protected and private would be fine too, depending on what makes sense 
    } 
} 

Chỉnh sửa: trên thực tế, tôi không nhận định câu hỏi và kể từ giao diện là tĩnh anyways, đây là một đoạn mã được cập nhật:

public class OuterClass { 
    public static InnerClass { //static inner class making OuterClass just be a namespace 
    public interface InnerInnerInterface { //protected and private would be fine too, depending on what makes sense 
    } 
    } 
} 

Như một giải pháp bạn có thể xác định một lớp bên trong trừu tượng bên trong, với nhược điểm là bạn phải tuân theo ràng buộc thừa kế đơn.

+0

Hmm, thú vị! Tôi không bao giờ biết rằng giao diện có thể được khai báo là tĩnh. "Tĩnh" có nghĩa là gì ở đây? Tôi đã thử giao diện tĩnh của Google nhưng chưa tìm ra bất kỳ thứ gì. P/s: Chỉ cần chỉnh sửa bài đăng của tôi ở dòng bạn trích dẫn, để sửa lỗi ngữ pháp. –

+2

@ W.N .: Giao diện ẩn hoàn toàn. Tuyên bố đó chỉ là màu đỏ. –

+1

@Ryan điểm tốt, tôi cũng chỉ đọc lại câu hỏi và sẽ cập nhật câu trả lời của tôi. – Thomas

1

Các lớp bên trong được coi là chi tiết triển khai của lớp cấp cao nhất và do đó sẽ ẩn với khách hàng. Bất kỳ chức năng nào bạn muốn truy cập vào một lớp bên trong nên được thực hiện thông qua lớp cấp cao nhất, bởi vì khái niệm nói, chức năng đó sẽ chỉ hiển thị như chức năng của lớp cấp cao nhất, sao cho trình thiết kế lớp có thể hoán đổi hay nói cách khác thay đổi đáng kể các lớp bên trong mà không làm hỏng các bản dựng của khách hàng.

+2

Đó là tất cả vấn đề của ý kiến. Nếu các lớp bên trong chỉ dành cho việc sử dụng nội bộ của lớp cha, bạn sẽ không được phép làm cho chúng thành 'public'. – skaffman

2

Theo định nghĩa, một lớp cấp cao nhất và các lớp bên trong của nó được kết hợp chặt chẽ. Giao diện là một phương tiện để giảm khớp nối.

+1

Thậm chí nếu tôi chỉ cần sử dụng riêng giao diện đó cho lớp bên trong? –

+0

Đó không nhất thiết phải là một đối số tốt, vì tôi đã viết một số giao diện riêng tư, lồng nhau được sử dụng chỉ trong phạm vi của một lớp duy nhất. –

4

Hãy suy nghĩ về ngữ cảnh tĩnh và không tĩnh. Một lớp "cấp cao nhất" thiết lập một bối cảnh tĩnh vì nó có thể được truy cập mà không có bất kỳ cá thể kèm theo nào. I E. bạn có thể truy cập các lớp cấp cao nhất từ ​​một phương thức chính. Điều tương tự cũng áp dụng cho bất kỳ thành viên tĩnh nào của một lớp cấp cao nhất. Tuy nhiên, một lớp bên trong không tồn tại trong * cũng như không thiết lập bất kỳ ngữ cảnh tĩnh nào. Do đó nó không thể có bất kỳ thành viên tĩnh nào, và nó chỉ có thể được truy cập thông qua một cá thể của lớp chứa của nó, như các hàm tạo và các thành viên thể hiện khác. Từ một phương pháp chính, bạn sẽ không thể nói Outer.Inner.SOME_FIELD vì các thành viên của một lớp bên trong chỉ có ý nghĩa đối với lớp chứa.

* loại

+0

Câu trả lời này sẽ làm cho câu trả lời của Thomas rõ ràng hơn. +1. –

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