Подтвердить что ты не робот

Почему Java запрещает наследование внутренних интерфейсов?

т.е. почему следующая "циклическая зависимость" невозможна?

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

Так как интерфейсы не ссылаются на внешний класс, это должно быть разрешено; однако компилятор заставляет меня определять те интерфейсы вне класса. Есть ли логическое объяснение этого поведения?

4b9b3361

Ответ 1

Соответствующие правила в спецификации:

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

Класс C напрямую зависит от типа T, если T упоминается в расширении или реализует предложение C либо как суперкласс, либо суперинтерфейс, либо как квалификатор суперкласса или суперинтерфейса.

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

Интерфейс я напрямую зависит от типа T, если T упоминается в предложении extends я либо как суперинтерфейс, либо как определитель в имени суперинтерфейса.

Поэтому, если A extends|implements B.C, A зависит как от C, так и от B. Затем Spec запрещает круговые зависимости.

Мотивация включения B в зависимость неясна. Как вы уже упоминали, если B.C продвигается до верхнего уровня C2, не так много отличается от системы типов, поэтому почему A extends C2 в порядке, но не A extends B.C? Предоставленный вложенный тип B.C имеет некоторый prviledged доступ к содержимому B, но я не могу найти что-либо в спецификации, что делает A extends B.C неприятным.

Единственная проблема заключается в том, что C является внутренним классом. Предположим, что B=A, A extends A.C должно быть запрещено, поскольку существует круговая зависимость "охватывающего экземпляра". Вероятно, это настоящая мотивация - запретить внешнему классу наследовать внутренний класс. Фактические правила более обобщены, потому что они проще и имеют смысл даже для не-внутренних классов.

Ответ 2

Представьте, что вы являетесь компилятором.

Мы говорим, что вы создаете класс Something. Этот класс реализует Поведение... Но Поведение еще не существует, потому что что-то еще не зарегистрировано...

Вы понимаете проблему?

Смотрите поле класса, которое содержит вещи. Поведение содержится в окне "Кое-что". Но чего-то не существует.

Ответ 3

Простой факт, что спецификации языка запрещают, должно быть достаточно.

Некоторые причины, о которых я мог подумать:

  • Это не было бы полезно.

  • По каким-либо причинам вы можете использовать это, я уверен, что существуют лучшие варианты.

  • В дочерних классах должны распространяться базовые классы, так почему бы вам объявить базовый класс внутри своего собственного ребенка?

  • Было бы контринтуитивно, если бы отдельный класс расширил ваш внутренний класс.