How to make an outer class inherited from an inner class?

前端 未结 7 1164
执笔经年
执笔经年 2020-12-19 04:08

How can I make something like this work:

class Outer {
  int some_member;

  abstract class InnerBase {
    abstract void method();
  }
}

class OuterExtends         


        
7条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-19 04:48

    I haven't tried WhiteFang34's answer. It might work, but I'm not clear on it ...

    If you really want to define an extension of your inner class elsewhere than in the outer class, the most natural thing would be to define it as an extension of the inner class in another outer extending your outer class as follows:

    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);
        }
      }
    }
    

    I haven't actually run this code either, but it should work.

    Update:

    Based on the comment thread, I have now compiled and run both my code above and WhiteFang34's code.

    Both in fact work, but as noted in the comments by Paŭlo Ebermann, both create two copies of the outer inside the instantiated inner class.

    I'm going to upvote Paŭlo's answer, and would advocate just not trying to do this by either tactic, as it's really an abuse of the inner class mechanism.

    Just make your extended inner classes live inside the same outer class!

    Update 2:

    What happens in my code, based on runtime examination using a debugger and on examining the output from javap inspections of the classes, is that both InnerBase and OuterExtendsOuter$InnerExtendsInner have synthetic private final fields named this$0. Because no constructors are explicitly defined, the default constructors are used, and the code snippet

        OuterExtendsOuter outer = new OuterExtendsOuter();
        Outer.InnerBase inner = outer.new InnerExtendsInner();
    

    causes these two fields to both reference outer.

    In other words, Paŭlo's comment is entirely correct.

    By further experimentation, the same actually happens if you extend InnerBase in another inner class of Outer, so it has little to do with it being defined in the same outer class or an extension of it, but is in fact an outcome of how non-static inner classes are handled generally.

    I suspect this is documented somewhere, but I haven't seen that.

    Probably best to mix inheritance and inner classes as little as possible!

提交回复
热议问题