为什么这个java程序的结果是'44'?

时间:2014-01-06 05:12:45

标签: java

我认为结果可能是'43',因为q的类型是'poly 1'。然而,结果是“44”。我无法理解。请给我答案。

class poly1 {
int a;
public poly1(){
    a = 3;
}
public void print_a(){
    System.out.print(a);
}
}
public class poly2 extends poly1{
public poly2(){
    a = 4;
}

public void print_a(){
    System.out.print(a);
}

public static void main(String[] args){
    poly2 p = new poly2();
    p.print_a();

    poly1 q = new poly2();
    q.print_a();
}

}

6 个答案:

答案 0 :(得分:2)

当你调用类的构造函数时,首先调用类的超类型构造函数(直到没有超类型)。

当您调用

new poly2();

首先调用poly1构造函数(因为poly1是超级类型poly2),将a设置为3然后{{1调用构造函数,将poly2设置为a,这就是您所看到的。


  

q的类型是'poly 1'

似乎让您感到困惑的是以下代码

4

变量poly1 q = new poly2(); 被声明为类型q。这种情况没有区别。实际上重要的是对象的运行时类型。这是由poly1声明决定的。在这种情况下,对象是动态类型new

答案 1 :(得分:2)

运行此程序时,请

    poly2 p = new poly2();

a的值是4,因为它由poly2的构造函数初始化,再次在

     poly1 q = new poly2();

a的值由poly2到4的构造函数初始化,因此它将再次打印4,输出为“44”。 每次u实例化“p”和“q”时,“a”的值首先由poly1的构造函数初始化,并且“a”的calue再次由类poly2的构造函数初始化,因为poly2扩展了poly1类。

尝试调试代码,您将了解程序的确切流程。

根据语言规范,在进行super()调用之前,甚至不会初始化实例变量。

这些是在类实例创建/

的构造函数步骤中执行的步骤
  • 将构造函数的参数分配给此构造函数调用的新创建的参数变量。

  • 如果此构造函数以同一个类中的另一个构造函数的显式构造函数调用(第8.8.7.1节)开头(使用此方法),则使用这五个相同步骤计算参数并以递归方式处理该构造函数调用。如果该构造函数调用突然完成,则此过程突然完成,原因相同;否则,继续步骤5.

  • 此构造函数不以同一类中另一个构造函数的显式构造函数调用开头(使用此方法)。如果此构造函数用于Object以外的类,则此构造函数将以超类构造函数的显式或隐式调用开始(使用super)。使用这五个相同的步骤评估参数并递归处理超类构造函数调用。如果该构造函数调用突然完成,则此过程突然完成,原因相同。否则,请继续执行步骤4.

  • 为此类执行实例初始值设定项和实例变量初始值设定项,将实例变量初始值设定项的值按从左到右的顺序分配给相应的实例变量,在这些顺序中它们以文本方式出现在源代码中类。如果执行任何这些初始值设定项导致异常,则不会处理其他初始化程序,并且此过程会突然完成同样的异常。否则,请继续步骤5.

  • 执行此构造函数的其余部分。如果执行突然完成,则此过程突然完成,原因相同。否则,此过程正常完成。

答案 2 :(得分:1)

对我之前的回答感到抱歉。显然,我没有正确看到这个问题......

public static void main(String[] args){
    poly2 p = new poly2();
    p.print_a();

    poly1 q = new poly2();
    q.print_a();
}

现在,当你这样做时:

poly2 p = new poly2();

以下情况发生..

  
      
  1. 调用poly2构造函数。
  2.   
  3. poly2构造函数将创建调用转发给poly1构造函数。
  4.   
  5. a的值为3(在poly1构造函数中初始化)
  6.   
  7. 控件返回到poly2构造函数
  8.   
  9. a在poly2构造函数中设置为4。
  10.   

同样的事情也发生在第二种情况中。

答案 3 :(得分:0)

他们都知道Poly2,所以他们使用Poly2的结构功能,所以控制台显示“44”

答案 4 :(得分:0)

通过查看对象来调用方法。在你的情况下,对象是Poly2类,所以在这两种情况下它都会调用Poly2类的print_a方法。

添加

这里执行构造函数。构造函数的执行顺序是第一个基类构造函数,然后是派生类构造函数。

答案 5 :(得分:0)

运行此程序时,请在以下行

poly2 p = new poly2();

a的值是4,因为它由poly2的构造函数初始化,再次在下面的行

poly1 q = new poly2();

你创建的引用是poly1但是在运行时对象是由poly2创建的,所以在这一行中,一个值变为4,这就是为什么你得到的结果44