【问题标题】:What is the order of Print Out about NEW Keyword in Inheritance?继承中新关键字的打印顺序是什么?
【发布时间】:2016-03-31 19:33:00
【问题描述】:

这实际上是我感到困惑的一个面试问题的一部分。

class A
{
   public A()
   {
        System.out.println("A") ;
    }
 }

 class B extends A
 {
     public B()
     {
         System.out.println("B") ;
     }
 }


 A a1 = new B();
 System.out.println() ;
 A a2 = (A) new B() ;

那么问题是打印出来的内容是什么?

起初我认为它应该像这样打印出来

B
A

B
A

但我在家里跑步后,它给了

A
B

A
B

我知道它是继承然后将 B 向上转换为 A,这也是合法的语法,但为什么 A 在 B 之前打印?

【问题讨论】:

  • 如果构造函数是super(); System.out.println("B");,我会预料到这一点,但现在我很困惑。
  • @Gendarme:没有任何明确的super(...)this(...)super() 是隐含的。
  • 必须始终先初始化超类。

标签: java inheritance constructor upcasting


【解决方案1】:

为什么 A 在 B 之前打印?

因为基本上超类构造函数的主体是在子类构造函数的主体之前执行的。

将您的 B() 构造函数视为隐式:

public B()
{
    super(); // This invokes A's constructor
    System.out.println("B") ;
}

完整的细节在JLS 12.5。特别是:

此构造函数不是以显式调用同一类中的另一个构造函数开始的(使用this)。如果此构造函数用于 Object 以外的类,则此构造函数将以显式或隐式调用超类构造函数开始(使用 super)。使用这五个相同的步骤递归地评估超类构造函数调用的参数和过程。

【讨论】:

  • 如果是B b1 = new B();,也会发生这种情况吗?投射到A 完全无关紧要?
  • @Gendarme:是的,完全不相关。这只是“创建 B 的新实例的过程”。
【解决方案2】:

父类A的构造函数在子类B的构造函数之前被调用。换句话说,它相当于:

public B() {
    super();
    System.out.println("B");
}

【讨论】:

    猜你喜欢
    • 2014-02-27
    • 2015-06-07
    • 2012-09-21
    • 2015-08-01
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-13
    • 2021-03-20
    相关资源
    最近更新 更多