How does Java inheritance work when inner classes are involved

inheritance, inner-classes, java, polymorphism

Solution

Variable are not "overriden" as methods are.

In your call, you expected `x` to be the `Child`'s one but it isn't because `x` is a variable, not a method.

But pay attention: Your reference type is `ParentClass` so `obj.x` points to the `ParentClass`'s `InnerClass` attribute even though the real instance behind `parentClass` is a `ChildClass`!

In order to display your expected sentence, you have to change the type reference to `ChildClass`:

public static void main(String[] args) {
      ChildClass obj = (new InnerClassTest()).new ChildClass();
      obj.x.speak();
}

To better understand the concept, try to define a method in both `ParentClass` and `ChildClass` classes:

public InnerClass getInnerClass(){
  return x;
}  

and make `x` private.

so that "override concept" applies.

Your final call would be in this case:

ParentClass obj = (new InnerClassTest()).new ChildClass();
obj.getInnerClass().speak();

To alter the behavior of the inner classes, think of Template method pattern or better: Strategy pattern (since more respectful of DIP)

Problem

I am having trouble understanding how inheritance works in Java when inner classes are present. I'm currently working on something where a child class needs to slightly change the functionality of the inner class of it's parent. I've come up with an simpler, analagous example below. I expected this code to print "I am a ChildClass.InnerClass" but instead it prints "I am a ParentClass.InnerClass". Why is this? Also, if I change the obj object in main to be of type ChildClass then the output changes to "I am a ChildClass.InnerClass". Why is this? In general, what is the recommended way of altering the behavior of an object's parent class's inner object? ``` class InnerClassTest { //----------------------------------------------------------------------- // PARENT CLASS class ParentClass { public ParentClass() { x = new InnerClass(); } InnerClass x; class InnerClass { public void speak() { System.out.println("I am a ParentClass.InnerClass"); } } } //----------------------------------------------------------------------- // CHILD CLASS class ChildClass extends ParentClass { public ChildClass() { x = new InnerClass(); } InnerClass x; class InnerClass extends ParentClass.InnerClass { public void speak() { System.out.println("I am a ChildClass.InnerClass"); } } } //----------------------------------------------------------------------- // MAIN public static void main(String[] args) { ParentClass obj = (new InnerClassTest()).new ChildClass(); obj.x.speak(); } } ```

Original source