How does polymorphism work for inner classes?

≯℡__Kan透↙ 提交于 2020-01-06 03:19:07

问题


When I tried to understand how to work with collections in java, I realised that I don't understand how polymorphism works for inner classes.

Simple code example:

 class Parent {
    public static void main(String[] args) {
        new Parent().newInnerClass().myMethod();
        new Child().newInnerClass().myMethod();
    }

    public I newInnerClass() {
        return new InnerClass();
    }

    private final class InnerClass implements I {

        @Override
        public void myMethod() {
            System.out.println("parent inner class");
            foo();
        }
    }

    public void foo() {
        System.out.println("foo from parent");
    }


}

class Child extends Parent {
    public void foo() {
        System.out.println("foo from child");
    }
}

interface I {
    void myMethod();
}

result:

parent inner class
foo from parent
parent inner class
foo from child

Therefore first link affects the third method invocation. It is surprising to me.

Initially I thought that needed methods selected accordind to the link. But new Parent().newInnerClass() and new Child().newInnerClass() are links to InnerClass from Parent.

Can you clarify my misunderstanding?

P.S.

If InnerClass was in Child and extended InnerClass from Parent - this behaviour wouldn't be surprising for me.


回答1:


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.



来源:https://stackoverflow.com/questions/23181847/how-does-polymorphism-work-for-inner-classes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!