java - 多态性如何用于内部类?

标签 java inheritance polymorphism overriding inner-classes

当我试图了解如何在 Java 中使用集合时,我意识到我不明白多态性如何用于内部类。

简单代码示例:

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

结果:

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

因此第一个链接会影响第三个方法调用。这让我很惊讶。

最初我认为需要根据链接选择所需的方法。但是 new Parent().newInnerClass()new Child().newInnerClass() 是从 ParentInnerClass 的链接。

你能澄清一下我的误解吗?

附注

如果 InnerClass 位于 Child 中并从 Parent 扩展 InnerClass - 这种行为对我来说并不奇怪。

最佳答案

内部类中的多态性没有特殊规则。

内部类与普通类有两点不同:

  • 内部类持有对其包含对象的隐式引用
  • 内部类可以访问其包含类的私有(private)方法(此处不相关)

这就是如何在没有内部类的情况下重写示例:

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

此代码产生与您相同的输出,因为当您调用时

new Child().newInnerClass().myMethod();

containingObject 是一个 Child,而 containingObject.foo() 是常规多态调用。

当您使用内部类时,编译器在幕后执行相同的操作。

关于java - 多态性如何用于内部类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23181847/

相关文章:

java - org.springframework.web.servlet.PageNotFound noHandlerFound警告: No mapping found for HTTP request with URI

java - 如何从其他模块测试 Maven 插件 (Mojo)

javascript - 当使用 apply() 和 call() 方法很容易继承时,为什么人们在 JavaScript 中使用原型(prototype)?

java - 更换开关盒 : interface vs abstract class

c# - 对第 3 方类的多态扩展

java - Bean 验证组 - 验证内部类

java - 根据百分比选择一个值

ruby - 在 Ruby 中调用 super 方法

java - JVM JIT 能否专门化子类中的非覆盖方法?

java - 如何使用多态性将对象映射到辅助类?