简体   繁体   中英

Two questions on inner classes in Java (class A { class B { } })

Sorry for the bad title, but I couldn't think of a better one.

I'm having a class A and a class B which is kind of a sub class of A, like so:

(Is there actually a correct name for it? Isn't "sub class" reserved for inheritance?)

class A {
    int i = 0;
    class B {
        int j = 1;
    }
}

class Test {
    public static void main() {
        A a = new A();
        B b = a.new B();
        A c = ??? b ??? // get "a" back
    }
}

From B every property of A can be accessed, therefore both, ai and bi, return 0. Now, I'm wondering whether it's somehow possible to retrieve the original object of type A out of b, as b contains everything that a contains? Simple casting apparently doesn't do the trick.

Second one:

class A {

    void print() {
        System.out.println("This is class A.");
    }

    class B {
        void print() {
            // <--- How to access print() of class A (like this.A.print() or smth)? 
            System.out.println("This is class B.");
        }
    }
}

You could alternatively also provide me with some good resources on this topic, as I've been too stupid to find a good one so far.

Thanks in advance. :)

There doesn't seem to be a way to access the outer class from outside. But you can do it like this:

class A {
    int i = 0;
    class B {
        final A outer = A.this;
        int j = 1;
    }
}

class Test {
    public static void main() {
        A a = new A();
        A.B b = a.new B();
        A c = b.outer // get "a" back
    }
}

ClassName.this will be the instance of the outerclass associated with the instance of an inner class.

You can access it with the ParentClass.this syntax from within the inner class.

eg

public class Outter
{
    class Inner {
        public Outter getOutter()
        {
            return Outter.this;
        }
    }

    public Inner getInner(){
        return new Inner();
    }
}

class Runner{
    public static void main(String[] args){
        Outter out = new Outter(); 
        Outter.Inner inner = out.getInner();

        System.out.println(inner.getOutter().toString());
    }
}

[Edit: My answer is appropriate for C# programmers, but I can't guarantee that its applicable to Java.]

B is an inner class, not a subclass of A. Additionally, B does not hold an instance of A, so your code as is cannot return any instance of A.

You need to restructure your classes as follows:

class A
{
    public class B
    {
       public A Parent;
       public B(A parent)
       {
          this.Parent = parent;
       }
    }
}

Now your B class has a field 'Parent' which returns its parent. You can use these classes as follows (this is C# syntax, because I don't know if Java has a different syntax for instantiating inner classes):

public static void Main(String[] args)
{
    A parent = new A();
    A.B child = new A.B(child);
    A backToParent = child.Parent;
}

Of course, creating your B class in this way seems little funny: technically, you can pass in any parent. It would probably be better to rewrite your A class with a method which returns a B:

class A
{        
    public class B
    {
       public A Parent;
       public B(A parent)
       {
          this.Parent = parent;
       }
    }

    public B getChild()
    {
        return new B(this);
    }
}

public static void Main(String[] args)
{
    A parent = new A();
    A.B child = A.getChild();
    A backToParent = child.Parent;
}

this seemed to work for me

class A {
    int i = 0;
    class B {
        int j = 1;
    }
}

class Test {
    public static void main() {
        A a = new A();
        A.B b = a.new B();
        A c = (A)b.getClass().getDeclaredField("this$0").get(b);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM