为什么在Java中使用构造函数两次
我对Java是全新的。我对OOP有很好的经验,但这让我觉得有点奇怪。我正在读《思考Java,如何像计算机科学家一样思考》一书。它将讨论构造函数以及如何使用它们。无论如何,让我开门见山。代码如下:为什么在Java中使用构造函数两次,java,oop,Java,Oop,我对Java是全新的。我对OOP有很好的经验,但这让我觉得有点奇怪。我正在读《思考Java,如何像计算机科学家一样思考》一书。它将讨论构造函数以及如何使用它们。无论如何,让我开门见山。代码如下: class Time { int hour, minute; double second; public Time() { this.hour = 0; this.minute = 0; this.second = 0.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);
}
}
我的问题特别涉及这一点:
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;
}
为什么我要花这么长的时间来写呢?或者这是正确的方法?谁能给我解释一下,谢谢!: 没有,因为您建议的
public Time() {
this.hour = hour;
this.minute = minute;
this.second = second;
}
不会在一小时、一分钟或一秒钟内过去。因此,这相当于
public Time() {
this.hour = this.hour;
this.minute = this.minute;
this.second = this.second;
}
这将使每个字段都为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);
public Time() {
this.hour = 0;
this.minute = 0;
this.second = 0.0;
}
您将以不同的方式初始化对象,这是使用多个构造函数的好处之一
我希望我能帮助您在您的示例中,您正在为自己分配值:
public Time() {
this.hour = hour;
this.minute = minute;
this.second = second;
}
为了消除您的困惑,实际上以其当前形式,此构造函数:
Time t=new Time(1,1,1.1);
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
}
理由很简单:有人想要另一种方法来创建新的时间实例。但是,由于小时、分钟或秒的值不是隐式已知的,因此将使用默认值对其进行实例化 你不能按照你的建议去做,因为正如其他人所指出的,这相当于给自己赋值。然而,它也会产生同样的效果,因为。这里的主要问题是它很难阅读 我所见过的这种模式的大多数用例都使用了这个关键字,所以这样的分配只发生一次,而自我分配发生的可能性较小
public Time() {
this(0, 0, 0);
}
在其他情况下,如果您想使用构造函数执行这类操作,可以将默认值设置为您想要的任何其他参数,并传入您关心的参数。例如,带有小时的偏移量如下所示:
public Time(int hour) {
this(hour, 0, 0);
}
…您只需编写这些值的实际赋值一次
下面,通常的构造函数是初始化实例变量。构造函数的每一行都将实例变量初始化为任意默认原语值(在本例中为午夜)。由于括号为空,构造函数不接受任何参数。您可以使用与使用任何其他对象的名称相同的方法来使用它。例如,您可以读取和写入该方法的实例变量,并将其作为参数传递给其他方法。但您不声明该方法,也不使用new创建它。事实上,你甚至不允许给它做作业!这是由系统创建的;您所要做的就是将值存储在其实例变量中
public Time() {
this.hour = 0;
this.minute = 0;
this.second = 0.0;
}
下面的构造函数是重载的,就像任何其他方法一样,这意味着您可以提供具有不同参数的多个构造函数。java通过将新命令的参数与构造函数的参数匹配来知道调用哪个构造函数
一个构造函数不接受任何参数,另一个构造函数接受与实例变量列表相同的参数列表,这是非常常见的。参数的名称和类型与实例变量的名称和类型完全相同。构造函数所做的只是将信息从参数复制到实例变量
public Time() {
this.hour = 0;
this.minute = 0;
this.second = 0.0;
}
注意,重载构造函数提供了先创建对象,然后填充空白,或者在创建对象之前收集所有信息的灵活性。
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命令时,系统会为新对象分配空间,然后调用构造函数来初始化实例变量
// 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);
大体上,第一次调用新命令时,我们没有提供
参数,因此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);
// another way to do the same thing
Time t2 = new Time (11, 8, 3.14159);
System.out.println (t2);
第二次调用新命令时,我们将提供与第二个构造函数的参数匹配的参数。这种初始化实例变量的方法更简洁,效率也更高一些,但它可能更难读取,因为不太清楚为哪些实例变量分配了哪些值
// 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);
一个是无参数的。一个拿args。他们不同,做不同的事情。当你尝试你想要做的事情时发生了什么?也许写这篇文章的更好方法是让无参数构造函数调用参数构造函数,使用这个0,0,0.0.Hmm,这确实更有意义。谢谢你好,@Emz,我讨厌粗鲁,但你知道我必须等10分钟才能接受答案,对吗?你从来没有给过我机会:注释是短暂的,它们可能随时消失。实际上,如果你想创建一个具有默认字段值的时间对象,就需要no-arg构造函数,但是给定的构造函数的主体什么都不做。默认的无参数构造函数只有在没有编写其他构造函数的情况下才存在。@CarlManaster我知道,但不要混淆默认构造函数和无参数构造函数。您好,@Juned,这更有意义,谢谢。现在我不想麻烦了,但是你能解释一下两个构造函数之间的区别吗,一个有参数,一个没有参数。我仍然有点困惑。@没有参数的MichaelJones正在将值设置为一些硬默认值,而参数构造函数使用动态参数值初始化它们。噢谢谢你,这让我觉得很有道理谢谢你。到目前为止,这是最好的答案,它解释了100倍于此再次感谢您,非常有帮助,我想我现在已经非常理解了!:D