2014-02-22 172 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()是更多的信息什麼它構造不僅僅是一個重載的構造函數。我只是假設你的教授爲什麼告訴你這個主意不好。