我看到有些人在这里做第二个构造函数中的东西:
public class Apples {
String color;
int quantity;
public Apples(String color, int quantity) {
this.color = color;
this.quantity = quantity;
}
public Apples(String color) {
this(color, 0);
}
}
这样做的原因是什么?对我来说,似乎你正在调用一个额外的方法(构造函数)只是为了节省几行。我记得几年前一位教授说这是不好的做法,但我不记得他这样说的理由。
答案 0 :(得分:10)
今天的计算机速度如此之快,以至于为了便于阅读和删除代码冗余而调用其他方法比使用无人能理解的复杂和重复代码更令人感激。
编程不只是编码,而是远不止于此。您必须通过代码向将要阅读您的代码的人讲述一个故事。建议使用干净的代码。
因此,如果从另一个构造函数调用构造函数保存10行代码,那就更好了。今天的编译器非常智能,它们将为这些场景生成非常有效的字节/机器代码。
答案 1 :(得分:7)
DRY =不要重复自己。这不仅可以减少代码,还可以更轻松地理解代码。您可以看到具有一个参数的构造函数与使用额外零调用另一个参数的构造函数相同。在更复杂的例子中,这会产生更大的不同。
WET =写两次;)
答案 2 :(得分:4)
因为如果不这样做,它会比你所拥有的代码重复更好
public class Apples {
String color;
int quantity;
public Apples(String color, int quantity) {
this.color = color;
this.quantity = quantity;
}
public Apples(String color) {
this.color = color; // code duplication
this.quantity = 0;
}
}
答案 3 :(得分:2)
如果你认为你实现了第一个构造函数然后添加了第二个构造函数,那么我认为这不是一个坏主意。 而不是编写所有这些初始化代码,通过使用现有的(并且经过验证+其他代码很好地使用而没有问题)init块,您可以捎带它。
代码重复可能没有您想象的那么糟糕,但也存在人为错误的可能性。 您可以复制并粘贴现有的init块,但是如果您尝试手动键入,那么新构造函数中的新代码可能是
this.color = color; [班上的其他东西] =数量;
而不是
this.color = color; this.quantity = quantity;
错误的,我相信它会花时间来弄清楚这一点。 您可能认为不会发生这种情况,但是如果您有10个以上参数的类并且想要在不重用现有构造函数的情况下添加新构造函数,则可能容易出错。
答案 4 :(得分:2)
它可以被视为一些API设计实践,你提供(借口这个术语),但是让我们说泛型构造函数具有你提到的所有类实例变量作为参数:
public Apples(String color, int quantity) {
this.color = color;
this.quantity = quantity;
}
然后你实现一些额外的构造函数,这些构造函数可能需要一个或多个这个实例变量,你可以将a default value
影响到非指定的变量:
public Apples(String color) {
this(color, 0);
}
这里你正在影响数量实例变量的0,它也可以写成如下,并且与上面的代码完全相同(除了你试图重用定义的构造函数):
public Apples(String color) {
this.color = color;
this.quantity = 0;
}
这样你就会想到一些用户或同事降落并希望使用你编写的代码片段,但是他不太了解类在他们要实例化它们时可能采取的默认值(这是真的展示了更多复杂 exapmles);但作为优秀的设计师,你想到了他,并提供了constructors
的多样性,这应该可以缓解他的内容。
BR。
答案 5 :(得分:1)
可以delegate call
到another
constructor
使用“this(params)”作为
当前构造函数的第一个陈述。
我们实现构造函数调用委托 如果初始化过程相同 多个构造函数,它们只有不同之处 他们的投入。
在构造函数调用委托prg ctrl上 移动到另一个构造函数,执行 其中的代码然后回到了 跟随委托电话的下一行。
class Myclass1
{
int a,b;
Myclass1()
{
this(10,20);//delegate to Myclass(int,int)
System.out.println("Myclass1() got job done from Myclass1(int, int)");
}
Myclass1(int q, int w)
{
//this();//err recursive constructor invocation
System.out.println("Myclass1(int,int)");
a = q;
b = w;
}
void f()
{
System.out.println("in f()");
f(10);//delegate call to f(10)
System.out.println("done f()");
}
void f(int x)
{
System.out.println("x is " + x);
}
void disp()
{
System.out.println(a + " " + b);
}
public static void main(String args[])
{
Myclass1 m1 = new Myclass1();
Myclass1 m2 = new Myclass1(1,2);
m1.disp();
m2.disp();
System.out.println("-------FN CALL DELEGATION---------------");
m1.f();
m1.f(99);
}
}
答案 6 :(得分:1)
根据DRY规则,@ Peter Lawrey说这是一个很好的做法,但你的代码肯定不是最好的做法。为什么?因为重载构造函数不是最好的主意。相反,您可以使用静态工厂方法。有效的Java提到:
静态工厂方法的一个优点是,与构造函数不同,它们 有名字。
因此,使用静态工厂方法,您的代码将如下所示:
public class Apples {
String color;
int quantity;
private Apples(String color, int quantity) {
this.color = color;
this.quantity = quantity;
}
public static Apples newInstance(String color, int quantity) {
return new Apples(color, quantity);
}
public static Apples newEmptyInsatnce(String color) {
return new Apples(color, 0);
}
}
这样,方法Apples.newEmptyInstance()就其构造的内容而不仅仅是重载的构造函数提供了更多信息。我只是假设你的教授为什么说这是一个坏主意。