There are no special rules for polymorphism in inner classes.
Inner class differs from regular class in two things:
- Inner class holds an implicit reference to its containing object
- Inner class can access
private
methods of its containing class (not relevant here)
That's how you can rewrite your example without inner class:
class Parent {
...
public I newInnerClass() {
return new NotInnerClass(this);
}
...
}
class NotInnerClass implements I {
private final Parent containingObject;
public NotInnerClass(Parent containingObject) {
this.containingObject = containingObject;
}
@Override
public void myMethod() {
System.out.println("parent inner class");
containingObject.foo();
}
}
This code produces the same output as your, because when you invoke
new Child().newInnerClass().myMethod();
containingObject
is a Child
and containingObject.foo()
is a regular polymorphic call.
When you use inner class, compiler does the same thing behind the scenes.