Я не пробовал ответить WhiteFang34. Это может сработать, но я не совсем понимаю ...
Если вы действительно хотите определить расширение вашего внутреннего класса в другом месте, чем во внешнем классе, наиболее естественным было бы определить его как расширение внутреннего класса в другом внешнем расширении вашего внешнего класса следующим образом:
class Outer {
int some_member;
abstract class InnerBase {
abstract void method();
}
}
class OuterExtendsOuter extends Outer {
class InnerExtendsInner extends Outer.InnerBase {
void method() {
System.out.println(some_member);
}
}
}
Я на самом деле тоже не запускал этот код, но он должен работать.
Обновление:
Основываясь на ветке комментариев, я теперь скомпилировал и запустил как мой код выше, так и код WhiteFang34.
Оба на самом деле работают, но, как отмечено в комментариях Поло Эбермана, оба создают две копии внешнего внутри экземпляра внутреннего класса.
Я собираюсь поднять ответ Пауло и выступать за то, чтобы просто не пытаться сделать это с помощью какой-либо тактики, поскольку это действительно злоупотребление механизмом внутреннего класса.
Просто сделайте ваши расширенные внутренние классы живыми внутри того же внешнего класса!
Обновление 2:
То, что происходит в моем коде на основе проверки во время выполнения с использованием отладчика и проверки результатов проверок классов в javap, заключается в том, что как InnerBase
, так и OuterExtendsOuter$InnerExtendsInner
имеют синтетические частные конечные поля с именем this$0
. Поскольку конструкторы не определены явно, используются конструкторы по умолчанию и фрагмент кода
OuterExtendsOuter outer = new OuterExtendsOuter();
Outer.InnerBase inner = outer.new InnerExtendsInner();
заставляет эти два поля ссылаться на outer
.
Другими словами, комментарий Пауло совершенно правильный.
Путем дальнейших экспериментов то же самое на самом деле происходит, если вы расширяете InnerBase
в другом внутреннем классе Outer
, поэтому он имеет мало общего с его определением в том же внешнем классе или его расширением, но находится в факт, как обычно обрабатываются нестатические внутренние классы.
Я подозреваю, что это где-то задокументировано, но я этого не видел.
Вероятно, лучше всего смешивать наследование и внутренние классы как можно меньше!