简体   繁体   English

多态如何对内部类起作用?

[英]How does polymorphism work for inner classes?

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. 当我试图了解如何在Java中使用集合时,我意识到我不了解多态如何为内部类工作。

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 . 但是new Parent().newInnerClass()new Child().newInnerClass()是从ParentInnerClass链接。

Can you clarify my misunderstanding? 你能澄清我的误会吗?

PS PS

If InnerClass was in Child and extended InnerClass from Parent - this behaviour wouldn't be surprising for me. 如果InnerClass在Child中并且从Parent扩展了InnerClass这种行为对我来说并不奇怪。

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) 内部类可以访问其包含类的private方法(此处不相关)

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. containingObjectChildcontainingObject.foo()是常规的多态调用。

When you use inner class, compiler does the same thing behind the scenes. 当您使用内部类时,编译器在后台执行相同的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM