I should mention that I had figured out the specific programming issue after I had thought to ask this question, so this is less of a programming problem and more a question on the reasons behind the problem.
I had been testing the limitations of Java when using access modifiers, and started applying these tests to basic inheritance concepts.
Here is the code:
package test.Inheritance;
public class SuperClass {
private static int x = 0;
protected static int y = 1;
public static void main(String[] args){
SupplementalClass2 child = new SupplementalClass2();
NestedClass local = new NestedClass();
InnerClass test;
child.setObject(child.new InnerClass(){
@Override public void display(){System.out.println("Hey!");}
});
test = child.getObject();
System.out.println(test.equals(child.receiveObject));
SuperClass.NestedClass.display();
SuperClass.NestedClass2.display();
test.display();
child.display();
local.message();
}
public static class NestedClass {
public static void display()
{
System.out.println("x before first static context change: " + x);
x = 25;
System.out.println("x after first static context change: " + x);
}
public void message()
{
System.out.print("Nested Class Field Access Test: " + "before(" + y + ") | ");
y = 20;
System.out.println("after(" + y + ")");
}
}
public static class NestedClass2 {
public static void display()
{
System.out.println("x before second static context change: " + x);
x = 30;
System.out.println("x after second static context change: " + x);
}
}
public class InnerClass {
public void display(){}
}
}
abstract class SupplementalClass extends SuperClass {
protected String test = "Parent Class String";
protected InnerClass receiveObject;
}
interface SupplementalInterface {
public static final int test = 3;
public abstract void display();
}
class SupplementalClass2 extends SupplementalClass implements SupplementalInterface {
public void display()
{
System.out.println("Supplemental Interface Field Access Test: " + SupplementalInterface.test);
System.out.println("Supplemental Parent Field Access Test: " + super.test);
}
public void setObject(InnerClass in){
receiveObject = in;
}
public InnerClass getObject()
{
return receiveObject;
}
}
This is the fixed version: InnerClass
is given a method display()
to override the method in SupplementalClass2
.
Before, InnerClass
was empty and I tried to set the display method in the Anonymous Class instance, instead of the class itself, because I believed the inner class would inherit the abstract display method implemented through SupplementalInterface
.
So the question that I have is how do nested and inner classes access data in their holders if not through inheritance?
Inner class instances access the fields and methods of their outer class instance like any object accesses fields and methods of another object. The only difference is that, to be able to access private members, the compiler generates synthetic bridge methods (that are not private), called by the inner class, to access the private members.
See for example thus class:
If you compile it and call
javap -c Outer Outer.Inner
, you'll get the following output:As you see, the Outer class has two additional static methods:
access$000()
andaccess$100()
, which respectively call the private method and return the value of the private field. And the inner class goes through these methods to call the private method and access the private field.The public method and fields are accessed in the usual way, though, since nothing prevents an object to access a public member of another object.
I'll let you do the same experiment on nested classes and static members to see how it works precisely.