3

I know that if I want to extend inner class I should make something like this:

class Outer{
    class Inner{}
}

class My extends Outer.Inner{
    My(Outer outer){
        outer.super();
    }
}

But at this situation I don't understand how should I do? how to get enclosing instance of inner object?

class My extends Outer.Inner{
    My(Inner inner){
        // how to get enclosing instance of inner here
    }
}

this variant doesn't compile:

class Outer{
    class Inner{}
}

class My extends Outer.Inner{
    My(Outer.Inner inner){
        inner.Outer.this.super();
    }
}
gstackoverflow
  • 36,709
  • 117
  • 359
  • 710
  • 5
    Having to extend an inner class from outside the outer class is a clear sign that the inner class shouldn't be an inner class. Make it a top-level class, or make the My class an inner class as well. – JB Nizet Jun 24 '14 at 12:22
  • 2
    @JB Nizet it is theoretical question. – gstackoverflow Jun 24 '14 at 12:24

5 Answers5

2

If I understand you correctly, you want to access members of the outer class from the class extending the inner class.

You can only do this depending on the scope in which you declare your class. When you extend the inner class inside the outer class, all members are in scope and you can access them, something like

class Outer {
    private int var = 0;

    class Inner {}

    class My extends Outer.Inner {
        My() {
            var = 1;
        }
    }
}

If you declare the class outside the outer class, you can still access package private members if the extending type is in the same package

class Outer {
    int var = 0;

    class Inner {}

}

class My extends Outer.Inner {
    My( Outer outer ) {
        outer.super();
        outer.var = 1;
    }
}

If you're outside package scope, you might solve this by enclosing your class inheriting the inner class in a class inheriting the outer class to get access to its protected members:

class Outer {
    protected int var = 0;

    class Inner {}

}
class OuterMy extends Outer {
    class My extends Inner {
        My( Outer outer ) {
            var = 1;
        }
    }
}

If that isn't an option either, you only get access to the public members by storing the outer instance manually.

class Outer {
    public int var = 0;

    class Inner {}
}

class My extends Outer.Inner {
    private Outer outer;
    My( Outer outer ) {
        outer.super();
        this.outer = outer;
    }
    void method() {
        outer.var = 1;
    }
}

As far as I know those are your options, you cannot access the JVMs internal instance of the enclosing class

Einar Bjerve
  • 524
  • 2
  • 12
0

I believe this works if you make the inner class static.

That way, you can create an instance of the inner class even without the outer class.

EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
0

A non static inner class has an implicit pointer to the containing class (Outer.this). So you cannot create it outside of the outer class. But the following works fine :

class Outer{
    class Inner{}

    class My extends Inner{
        My(Inner inner){
            //You cannot access Outer.this outside the object itself
            //inner.Outer.this.super();
        }
    }
}

If the inner class is declared static it has no implicit pointer and the above limitation no longer applies.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

An inner class is just a normal class with a hidden field that holds a reference to the outer class instance that was used to create it.

You have correctly created a sub-class to override the inner class, so that sub-class is Inner. There will be no other "enclosing instance of inner object". You have this.

To access Outer from My, you'll have to either save it to another field in My or make a method in Inner to expose it because the field Outer.this is referring to is private.

billc.cn
  • 7,187
  • 3
  • 39
  • 79
0

I have found only one solution:

class Outer{
    class Inner{
        Outer outer = Outer.this;
    }
}

class My extends Outer.Inner{
    My(Outer.Inner inner){
        inner.outer.super();
    }
}
gstackoverflow
  • 36,709
  • 117
  • 359
  • 710