Java 中的嵌套虚拟 类

Nested virtual classes in Java

如果我们考虑以下代码,应该会发生多态性,因为它在 java 中的嵌套 classes 中是允许的,但是,当调用 inner class 构造函数时 polymorphism 确实not apply 即 new Innner1() 适用于声明的实例类型 不在实际类型上。

public class Outer {

    public class In {
        public In() {
            System.out.println("I am In");
        }
    }

    public static void main(String[] args) {
        Outer obj = new Outer2();
        obj.new In();
        Outer2 in2 = (Outer2) obj;
        in2.new In();
    }

}

class Outer2 extends Outer {
    public class In extends Outer.In {
        public In() {
            System.out.println("I am In2");
        }
    }
}

有人能帮我理解这种行为吗?

伙计们,我已经更新了代码并且编译正常并且没有 class 转换异常

请检查下面的输出。

I am In
I am In
I am In2

根据您的代码,您正在尝试在父对象中创建子对象 class。

public static void main(String[] args) {
        Outer obj = new Outer();

        obj.new Innner1();

        Outer2 obj2 = (Outer2) obj;
        obj2.new Innner1();
    }

理想情况下,这不是一个有效的情况,因为首先应该创建父 class,然后创建子,否则它将成为一个永无止境的层次结构。父对象将有子对象,子对象又将有一个父关系,然后。这就是当您执行当前代码时会得到类似

的响应的原因

线程异常 "main" java.lang.ClassCastException: Outer cannot be cast to Outer2 在 Outer.main(Outer.java:14) 我在

理想情况下你应该

 public class Outer {

    public class Innner1 {
        public Innner1() {
            System.out.println("I am In");
        }
    }
}

和 outer2 为

class Outer2 extends Outer {
    public class Innner1 extends Outer.Innner1 {
        public Innner1() {
            System.out.println("I am In2");
        }
    }

    public static void main(String[] args) {
        Outer obj = new Outer();

        obj.new Innner1();

        Outer2 obj2 = new Outer2();
        obj2.new Innner1();
    }
}

在这种情况下,结果将是

I am In
I am In
I am In2

你在这里看到父的内部 class 的构造函数在子 class 之前被调用。

这里发生了什么以及为什么会产生这个特殊输出:

 public static void main(String[] args) {
    Outer obj = new Outer2();  // Step 1
    obj.new In();              // Step 2
    Outer2 in2 = (Outer2) obj; // Step 3
    in2.new In();              // Step 4
 }

第 1 步:

您创建了 Outer2 的实例并将其分配给声明为 Outer 的变量 obj。这将执行 Outer2Outer 默认构造函数。

第 2 步:

您创建了一个 In。当两个内部 类 都不会被称为 In 时,真正创建的行为会更好地理解,但是当 obj 被声明为 Outer 时,调用 obj.new In(),由于 obj 的类型,将创建一个 Outer > In.

这是你的第一个输出:

I am In

第 3 步:

您再次创建 Outer2 的实例并将其分配给声明为 Outer2 的变量 in2!! <-- 这在这里非常重要。

这将执行 Outer2Outer 默认构造函数。

第 4 步:

你又创造了一个In。但是现在,由于 in2 被声明为 Outer2,调用 in2.new In(),由于 in2 的类型,现在将创建一个 Outer2 > In

现在你得到第二个和第三个输出:

I am In
I am In2