我是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;
}
为什么我要经历所有长期写作的额外麻烦?或者这是正确的方式吗?有人可以更好地向我解释一下,谢谢! :)
答案 0 :(得分:1)
不,因为你建议的替代
public Time() {
this.hour = hour;
this.minute = minute;
this.second = second;
}
不会传递hour
,minute
或second
。因此,它等同于
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;
}