2014-02-22 132 views
4

我看到有些人在这里的第二个构造做的东西,如:Java:通过构造函数调用构造函数,有什么意义?

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); 
    } 

} 

什么是这样做的原因是什么?对我来说,似乎你正在调用一个额外的方法(构造函数),只是为了节省几行。我回想几年前一位教授说这是不好的做法,但我不记得他这样说的原因。

+4

其原因是您可以使用相同的代码并在较小的构造函数中使用“默认”值。没有代码重复。 – pL4Gu33

+4

这是肯定的*不*不好的做法。 – qqilihq

+7

这是**最佳实践**,因为您将构造函数逻辑委托给单一方法。为什么你应该这样做有几个原因。将尝试找到一些关于它的文章... –

回答

10

计算机,你将不得不是如此之快,调用其他方法的可读性的原因和消除代码冗余是更欣赏比具有无法理解的复杂和重复的代码。

编程不仅仅是编码,更重要的是编程。您必须通过您的代码将故事讲给那些会阅读您的代码的人。清洁代码是推荐的方式。

因此,如果调用从另一个构造器的构造是节省10行代码,它的要好得多。今天的编译器非常聪明,它们将为这些场景生成一个非常高效的字节/机器码。

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; 
    } 

} 
+1

要说什么验证代码,你可能想要添加到contruction – Bohemian

+0

如果你需要计算出哪个构造函数调用,你将不得不找出差异在他们之间更加困难。 –

+1

@波希米亚好点! – Dima

7

DRY =不要重复自己。这不仅减少了代码,而且使代码更容易理解。你可以看到带有一个参数的构造函数和用另一个零值调用另一个参数的构造函数相同。在更复杂的例子中,这会产生更多的差异。

WET =两次写的一切;)

+2

+1对于WET-lol – Bohemian

2

我认为这是不,如果你认为你实现第一个构造函数,然后添加:第二个坏主意。 而不是编写所有这些初始化代码,通过使用现有的(和验证+由其他代码很好地使用没有问题)初始化块,您可以搭载它。

代码重复可能没有那么糟糕,你想,但有人为错误的可能性也是如此。 您可能会复制&粘贴现有的init块,但如果您尝试手动输入,则新构造函数中的新代码可能为

this.color = color; [课堂上的其他东西] =数量;

而不是

this.color = color; this.quantity = quantity;

错误,我相信它会花你的时间来弄清楚。 您可能认为这不会发生,但是如果您有10个以上参数的类并且想要添加新的构造函数而不重用现有的构造函数,那可能会出错。

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到数量实例变量,这也可能是软件写n的下方,这是相当与上面相同的代码(除非你想重用定义的构造函数):

public Apples(String color) { 
    this.color = color; 
    this.quantity = 0; 
} 

所以你在想的一些方式,用户或同事着落下来,想用你写的代码片段,但是并不知道类在实例化时可能需要的默认值(这实际上更多地展示在复杂的 exapmles中);但作为优秀的设计师,你想到了他,并提供了多样化的constructors,这应该可以缓解他的问题。

BR。

1

有可能delegate callanother constructor通过使用“这个(PARAMS)”作为当前构造的 第一条语句。

我们实施的构造函数调用代表团 如果初始化过程是相同的 多个构造函数,他们只 INT他们的投入是不同的。

在构造函数调用代表团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); 
    } 
} 
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()是更多的信息什么它构造不仅仅是一个重载的构造函数。我只是假设你的教授为什么告诉你这个主意不好。