【问题标题】:Why do these constructors run in this order?为什么这些构造函数按这个顺序运行?
【发布时间】:2015-10-19 08:55:39
【问题描述】:

我知道对象应该被创建成类似Class_name Object_name=new Classname() 的东西。在我的程序中,我创建了一个名为sup 的超类和一个名为der 的派生类。在我的子类构造函数中,我创建了一个像 sup obc = new der(); 这样的对象。没有任何错误,它编译并给出如下输出:

In Superclass with object passed as reference
In Superclass with no constructor
In derived class with no constructor

我不明白我是如何按此顺序获得输出的。为什么会这样?完整代码如下:

class sup {

  private int a, b, c;

  sup(sup ob) {
    System.out.println("In Superclass with object passed as reference");
    a = ob.a + 9;
    b = ob.b + 9;
  }

  sup(int a, int b) {
    this.a = a;
    this.b = b;
  }

  sup() {
    System.out.println("In Superclass with no constructor");
  }

}

class der extends sup {

  int d;

  der(der ob) {
    super(ob);
    sup obc = new der();
  }

  der() {
    System.out.println("In derived class with no constructor");
  }

  der(int a, int b, int c) {
    super(a, b);
    d = c;
  }
}

public class Test {

  public static void main(String args[]) {
    der ob1 = new der(3, 4, 5);
    der ob2 = new der(ob1);
  }
}

【问题讨论】:

  • 请确保您遵守 Java 命名约定,尤其是在这些形成性第一程序中。在Java中,我们使用PascalCase作为类名,保留camelCase作为变量。此外,请在发布之前格式化您的代码。
  • 由于我是 Java 新手,我很快就会学习 Java 命名约定。 @BoristheSpider
  • @Ashokkumar 与其将来学习,不如尝试现在编辑并学习。
  • @karthik 是的。我已经稍微格式化了代码。从现在开始,我将使用正确的命名约定。
  • @Ashokkumar 不要手动格式化代码!这是一项徒劳的任务。请您的 IDE 为您自动格式化。

标签: java object constructor


【解决方案1】:

第一个der 对象调用没有输出的super(a,b) 构造函数。第二个调用sup(sup ob),它给出第一行输出,然后它还调用new der(),当调用子类的默认构造函数时,也调用其超类的默认构造函数。这就是第二行的来源。然后new Der() 输出第三行。

【讨论】:

    【解决方案2】:

    第一次通话:

    der ob1 = new der(3, 4, 5);
    

    什么都不打印,因为它首先调用:

    der(int a, int b, int c) {
        super(a, b);
    

    调用者:

    sup(int a, int b) {
        this.a = a;
        this.b = b;
    }
    

    没有System.out.println 语句。没有调用其他构造函数,因为您从不显式调用它们。隐式的sup() 构造函数没有被调用,因为你已经调用了super(a, b)


    第二次调用:

    der ob2 = new der(ob1);
    

    调用这个构造函数:

    der(der ob) {
        super(ob);
        sup obc = new der();
    }
    

    首先发生的事情是这里的超级构造函数被调用:

    sup(sup ob) {
        System.out.println("In Superclass with object passed as reference");
    

    这是被打印出来的第一件事。然后,第二行:

    sup obc = new der();
    

    被调用,它调用这个构造函数:

    der() {
        System.out.println("In derived class with no constructor");
    }
    

    但是,这里有一个对super();隐式调用,它总是在子类中调用,即使您没有编写它。所以我们接着调用:

    sup() {
        System.out.println("In Superclass with no constructor");
    }
    

    这被打印出来,最后der的构造函数可以完成。

    请注意,如果您删除sup 的无参数构造函数der 将不再编译并出现错误:

    隐式超级构造函数ArrayListTest.sup() 未定义。必须显式调用另一个构造函数

    【讨论】:

      【解决方案3】:
      der(der ob) {
        super(ob);
        sup obc = new der();
      }
      

      首先调用超类构造函数sup(sup obj)(打印第一行输出),然后代码(没有任何理由)分配new der()

      但是在Java中,超类默认构造函数在子类构造函数之前被隐式调用,确实der()构造函数实现可以看作

      der()
      {
        super();
        System.out.println("In derived class with no constructor");
      }
      

      它解释了第二和第三个输出行。

      【讨论】:

        猜你喜欢
        • 2016-12-15
        • 2023-03-04
        • 1970-01-01
        • 2021-11-03
        • 1970-01-01
        • 1970-01-01
        • 2012-02-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多