【问题标题】:Nested virtual classes in JavaJava中的嵌套虚拟类
【发布时间】:2017-05-22 05:10:33
【问题描述】:

如果我们考虑以下代码,应该会发生多态性,因为它在 java 的嵌套类中是允许的,但是,当调用 inner class 构造函数时,polymorphism 不适用,即 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");
        }
    }
}

能否帮助我理解这种行为。

各位,我已经更新了代码,编译正常,没有类转换异常

请检查下面的输出。

I am In
I am In
I am In2

【问题讨论】:

  • 呃...你不能只将Outer 转换为Outer2...objOuter 的实例,但不是Outer2 的实例
  • 代码编译得很好,出来了...
  • 编译器不会告诉你(Outer2) obj 实际上并没有真正工作并且不会检查它。它只会在Runtime 处导致ClassCastException,因为您的工作是对类型进行有效和检查的转换(例如使用instanceof)。
  • 你期望什么输出?由于代码现在在类型转换方面是正确的,我会说一切都按预期工作,至少对我来说是这样。
  • 没有多态性,正如我在问题中提到的那样..

标签: java polymorphism inner-classes


【解决方案1】:

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

 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 默认构造函数。

第二步:

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

在这里你得到你的第一个输出:

I am In

第 3 步:

您再次创建Outer2 的实例并将其分配给声明为Outer2 的变量in2

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

第四步:

您再次创建In。但是现在,由于in2 被声明为Outer2,调用in2.new In(),由于in2 的类型,将创建一个Outer2 > Innow。

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

I am In
I am In2

【讨论】:

    【解决方案2】:

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

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

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

    的响应的原因

    线程“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
    

    您在这里看到父类的内部类的构造函数在子类之前调用​​'。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-23
      • 2020-03-06
      • 2021-07-31
      • 1970-01-01
      • 1970-01-01
      • 2019-05-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多