为什么在Java中使用构造函数两次

时间:2015-06-29 23:13:53

标签: java oop

我是Java的新手。我对OOP有很好的经验,但这有点让我觉得奇怪。我正在读这本书Think Java, How to Think Like a Computer Scientist。它正在讨论构造函数以及如何使用它们。无论如何,让我谈谈这一点。这是代码:

class Time {
    int hour, minute;
    double second;

    public Time() {
        this.hour = 0;
        this.minute = 0;
        this.second = 0.0;
    }

    public Time(int hour, int minute, double second) {
        this.hour = hour;
        this.minute = minute;
        this.second = second;
    }

    public static void main(String[] args) {
        // one way to create and initialize a Time object Time
        t1 = new Time();
        t1.hour = 11;
        t1.minute = 8;
        t1.second = 3.14159;
        System.out.println(t1);

        // another way to do the same thing Time
        t2 = new Time(11, 8, 3.14159); System.out.println(t2);
    }
}

我的问题具体涉及这个问题:

    public Time() {
        this.hour = 0;
        this.minute = 0;
        this.second = 0.0;
    }

    public Time(int hour, int minute, double second) {
        this.hour = hour;
        this.minute = minute;
        this.second = second;
    }

我很困惑为什么这样写。为什么这样?难道这不能简单地写成以下(?):

    public Time() {
        this.hour = hour;
        this.minute = minute;
        this.second = second;
    }

为什么我要经历所有长期写作的额外麻烦?或者这是正确的方式吗?有人可以更好地向我解释一下,谢谢! :)

6 个答案:

答案 0 :(得分:1)

不,因为你建议的替代

public Time() {
    this.hour = hour;
    this.minute = minute;
    this.second = second;
}

不会传递hourminutesecond。因此,它等同于

public Time() {
    this.hour = this.hour;
    this.minute = this.minute;
    this.second = this.second;
}

哪个会使每个字段0

答案 1 :(得分:1)

第一个示例创建了两个构造函数,提供了两种不同的构造对象的方法。第一个,没有提供参数,给出一个默认时间值。第二个采用当前的小时,分​​钟和秒,并根据参数构造时间对象。你建议的缩短不会做任何使用。单个构造函数中的赋值将是微不足道的,仍然将所有变量赋值为零。

答案 2 :(得分:1)

在您的示例中,您要为自己分配值:

public Time() {
    this.hour = hour;
    this.minute = minute;
    this.second = second;
}

为了消除您的困惑,实际上以其当前形式构建此构造函数:

public Time() {
     this.hour = 0;
    this.minute = 0;
    this.second = 0.0;
}

没有添加任何值,因为它使用默认值初始化字段。实例变量已经在对象创建时启动为默认值。

但是如果默认值不同,那么添加这样的构造函数是有意义的,例如:

public Time() {
    this.hour = -1;
    this.minute = -2;
    this.second = 5.0; // random defaults chosen
}

答案 3 :(得分:1)

下面,通常的构造函数是初始化实例变量。构造函数的每一行都将实例变量初始化为任意默认原始值(在本例中为午夜)。由于空括号(),构造函数不会接受任何参数。您可以像使用任何其他对象的名称一样使用它。例如,您可以读取和写入此实例变量,并且可以将其作为参数传递给其他方法。但是您没有声明这个并且您不使用new来创建它。事实上,你甚至不被允许做出任务!这是由系统创建的;您所要做的就是将值存储在其实例变量中。

public Time() {
    this.hour = 0;
    this.minute = 0;
    this.second = 0.0;  
}

以下构造函数重载,就像任何其他方法一样,这意味着您可以为多个构造函数提供不同的参数。并且java知道通过将new命令的参数与构造函数的参数进行匹配来调用哪个构造函数。

一个构造函数不带参数,一个构造函数带有一个与实例变量列表相同的参数列表,这很常见。参数的名称和类型与实例变量的名称和类型完全相同。所有构造函数都将参数中的信息复制到实例变量中。

请注意,重载构造函数可以灵活地创建对象,然后填充空白,或者在创建对象之前收集所有信息。

public Time(int hour, int minute, double second) {
 // this.hour, this.minute, this.second are instances variables
               this.hour = hour;
               this.minute = minute;
               this.second = second;
 }

创建新对象时    虽然构造函数看起来像方法,但您永远不会直接调用它们。相反,当您使用new命令时,系统会为新对象分配空间,然后调用构造函数来初始化实例变量。

在main中,第一次调用new命令时,我们不提供参数,因此Java调用第一个构造函数。接下来的几行为每个实例变量赋值。

// one way to create and initialize a Time object
 Time t1 = new Time ();
 t1.hour = 11;
 t1.minute = 8;
 t1.second = 3.14159;
 System.out.println (t1);

第二次调用new命令时,我们提供与第二个构造函数的参数匹配的参数。这种初始化实例变量的方式更简洁(并且稍微更有效),但它可能更难阅读,因为不清楚哪个值分配给哪些实例变量。

// another way to do the same thing
 Time t2 = new Time (11, 8, 3.14159);
 System.out.println (t2);

答案 4 :(得分:0)

这是类定义:

class Time {
    int hour, minute;
    double second;

    public Time() {
        this.hour = 0;
        this.minute = 0;
        this.second = 0.0;
    }

    public Time(int hour, int minute, double second) {
        this.hour = hour;
        this.minute = minute;
        this.second = second;
    }

    public static void main(String[] args) {
        // one way to create and initialize a Time object Time
        t1 = new Time();
        t1.hour = 11;
        t1.minute = 8;
        t1.second = 3.14159;
        System.out.println(t1);

        // another way to do the same thing Time
        t2 = new Time(11, 8, 3.14159); System.out.println(t2);
    }
}

但请记住,一个类可以有不同的实例,如果你创建一个新的对象,请按照以下步骤进行操作:

Time t=new Time();

在此对象中,您将拥有0,0,0.0。

但是在使用其他构造函数创建的另一个对象中:

Time t=new Time(1,1,1.1);

您将以不同的方式初始化对象,这是使用多个构造函数的好处之一。

我希望我可以帮助你

答案 5 :(得分:0)

理由很简单:有人想要另一种方法来创建Time的新实例。但是,由于未隐式知道小时,分钟或秒的值,因此会使用默认值进行实例化。

你不能做你所建议的事情,因为正如其他人所指出的那样,它等同于将价值分配给自己。但是,由于default value of an int field is 0,它会产生相同的效果。这里的主要问题是难以阅读。

我见过的这种模式的大多数使用案例都使用了this关键字,因此这种分配只发生一次,而且自我分配不太可能发生。

public Time() {
   this(0, 0, 0);
}

在其他情况下,如果您想使用构造函数执行此类操作,则可以将默认值设置为您想要的任何其他参数,并传入您关注的参数。例如,带小时的偏移量看起来像这样:

public Time(int hour) {
    this(hour, 0, 0);
}

...而且您只需要写出一次的实际值。

public Time(int hour, int minute, double second) {
    this.hour = hour;
    this.minute = minute;
    this.second = second;
}