In Java what is the relationship between a nested class and its outer class?
Asked Answered
K

1

7

When a nested class in instantiated how does it reference the outer class? Does it always extend the outer class or reference it another way? I was told that the inner extends the outer but then why doesn't the following example work?

For Example:

public class OuterClass {

    public String fruit = "apple";

    public class InnerClass {
        public String fruit = "banana";

        public void printFruitName(){
            System.out.println(this.fruit);
            System.out.println(super.fruit);
        }
    }

}

The above does not compile with an error for super.fruit saying that 'fruit' cannot be resolved. However if the inner class is specified to extend the outer class then it works:

public class OuterClass {

    public String fruit = "apple";

    public class InnerClass extends OuterClass {
        public String fruit = "banana";

        public void printFruitName(){
            System.out.println(this.fruit);
            System.out.println(super.fruit);
        }
    }

}

This seems to show that the inner class does not extend the outer class unless specifically specified.

Knopp answered 28/1, 2014 at 1:4 Comment(0)
M
8

There is no implicit sub-type relationship: your observation/conclusion is correct. (In the first case, super has the type of "Object" and "Object.fruit" does indeed not exist.)

An inner class (as opposed to "static nested class"), as shown, must be created within context of an instance of the outer class; but this is orthogonal to sub-typing.

To access a member of the outer class, use OuterClass.this.member or, if member is not shadowed, just member will resolve; neither super.member nor this.member will resolve to the outer class member.

Extending the outer class "fixes" the compiler error, but the code with this.fruit doesn't access the member of the enclosing OuterClass instance - it simply accesses the member of the InnerClass instance inherited from the superclass it extends.

Mythopoeic answered 28/1, 2014 at 1:7 Comment(4)
Could you clarify your last sentence please? I didn't know about OuterClass.this and was playing with it in the code posted in the question here, but when I have the inner class extend the outer class then both OuterClass.this.fruit and super.fruit do give me the outer instance's fruit value.Despond
@MikeB This appears to be the case, even though it is not, because the member was set (to the same value) when a new instance of OuterClass was created - e.g. for the real OuterClass instance and the superclass for the InnerClass instance. Change the fruit member variable of the OuterClass instance after it has been initialized but before creating an inner class instance - then you'll see a difference.Mythopoeic
You're right of course, I even did that in my original code but I saw a pear and overlooked the fact that the second set of output should have had 2 pears!Despond
+1 and thanks for getting the terminology right - many people say "inner class" when they mean "nested class".Abadan

© 2022 - 2024 — McMap. All rights reserved.