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(); } } ```