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();
}
}
Variable are not “overriden” as methods are.
In your call, you expected
xto be theChild‘s one but it isn’t becausexis a variable, not a method.But pay attention: Your reference type is
ParentClasssoobj.xpoints to theParentClass‘sInnerClassattribute even though the real instance behindparentClassis aChildClass!In order to display your expected sentence, you have to change the type reference to
ChildClass:To better understand the concept, try to define a method in both
ParentClassandChildClassclasses:and make
xprivate.so that “override concept” applies.
Your final call would be in this case:
To alter the behavior of the inner classes, think of Template method pattern or better: Strategy pattern (since more respectful of DIP)