2011-11-03 27 views
19

I.e. tại sao "phụ thuộc cyclic" sau đây không thể?Tại sao Java cấm thừa kế các giao diện bên trong?

public class Something implements Behavior { 
    public interface Behavior { 
     // ... 
    } 
} 

Vì giao diện không tham chiếu đến lớp bên ngoài nên được cho phép; tuy nhiên, trình biên dịch đang buộc tôi định nghĩa các giao diện đó bên ngoài lớp. Có lời giải thích hợp lý nào cho hành vi này không?

+0

Âm thanh như trình nạp lớp sẽ phải đọc lớp đầu tiên để biết giao diện cần xác định lớp ở vị trí đầu tiên ... Tôi không biết chi tiết về tải lớp, nhưng có vẻ khá rõ ràng. –

+2

@donneo: vì trình biên dịch phàn nàn về "sự phụ thuộc tuần hoàn" Tôi tưởng tượng nó đã biết loại nào được định nghĩa trong lớp bên trong. Nó có vẻ giống như một hạn chế tùy ý đối với tôi. –

+0

@PhilipK: bạn đang sử dụng trình biên dịch nào? Mine (Oracle JDK 6 và 7) chỉ phàn nàn rằng họ "không thể tìm thấy biểu tượng". Ngoài ra: câu hỏi hay, vì một giao diện lồng nhau không thực sự * dựa vào lớp bên ngoài theo bất kỳ cách thức kỹ thuật nào, điều này * có thể * là hợp pháp. –

Trả lời

11

quy tắc liên quan trong spec:

http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.4

Một lớp C trực tiếp phụ thuộc vào một loại T nếu T được đề cập trong mở rộng hoặc thực hiện khoản của C hoặc là một lớp cha hoặc superinterface , hoặc như một vòng loại của một tên siêu lớp hoặc siêu bề mặt.

http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.1.3

Một giao diện tôi trực tiếp phụ thuộc vào một loại T nếu T được đề cập trong mệnh đề của tôi hoặc là kéo dài như một superinterface hay như một vòng trong vòng một tên superinterface.

Do đó nếu A extends|implements B.C, A phụ thuộc vào cả hai CB. Spec sau đó cấm phụ thuộc vòng tròn.

Động lực bao gồm B trong sự phụ thuộc không rõ ràng. Như bạn đã đề cập, nếu B.C được thăng cấp lên cấp cao nhất C2, không có nhiều khác biệt với hệ thống kiểu liên quan, vậy tại sao A extends C2 là ok, nhưng không được A extends B.C?Cấp một loại lồng nhau B.C không có một số truy cập prviledged nội dung của B, nhưng tôi không thể tìm thấy bất cứ điều gì trong spec mà làm cho A extends B.C phiền hà.

Vấn đề duy nhất là khi C là một lớp bên trong. Giả sử B=A, A extends A.C nên bị cấm, bởi vì có sự phụ thuộc vòng tròn của "trường hợp kèm theo". Đó có lẽ là động lực thực sự - để cấm lớp ngoài từ lớp kế thừa bên trong. Các quy tắc thực tế được tổng quát hơn, bởi vì chúng đơn giản hơn và thậm chí còn có ý nghĩa tốt cho các lớp không bên trong.

10

Hãy tưởng tượng bạn là trình biên dịch.

Chúng tôi đang nói bạn tạo một lớp học. Lớp học này thực hiện Hành vi ... Nhưng Hành vi không tồn tại vì một số thứ chưa được đăng ký ...

Bạn có hiểu vấn đề không?

Xem lớp học làm hộp chứa mọi thứ. Hành vi được chứa trong hộp Cái gì đó. Nhưng cái gì đó không tồn tại.

+3

Đây sẽ là câu trả lời hợp lệ nếu câu hỏi là về C++. –

+1

Có, nhưng Hành vi là một giao diện và do đó không phụ thuộc vào việc tạo ra một cái gì đó. –

+0

Có, vì giao diện đó là một phần của Cái gì đó. Một cái gì đó cần phải tồn tại trước khi bạn có thể tham khảo Hành vi, nhưng để tạo một cái gì đó bạn cần tham khảo Hành vi. –

0

Thực tế đơn giản là các thông số ngôn ngữ cấm là đủ.

Một số lý do tôi có thể nghĩ ra:

  • Nó sẽ không có ích.

  • Vì bất kỳ lý do nào bạn có thể muốn sử dụng điều này, tôi chắc chắn rằng có các tùy chọn tốt hơn.

  • Lớp học con nên mở rộng các lớp cơ sở, vậy tại sao bạn khai báo một lớp cơ sở bên trong con của chính nó?

  • Sẽ phản trực giác khi có một lớp riêng biệt mở rộng lớp bên trong của bạn.

+0

Nó sẽ hữu ích cho các trường hợp mà chúng ta cần một giao diện gọi lại để chuyển đến một lớp khác. – ismailarilik

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