2012-02-10 25 views
7

比方說,有人給你一個類,Super,用下面的構造函數:如何在Java中有條件地調用不同的構造函數?

public class Super 
{ 
    public Super(); 
    public Super(int arg); 
    public Super(String arg); 
    public Super(int[] arg); 
} 

而且我們說你要創建一個子類Derived。你如何在Super有條件地調用構造函數?

換句話說,什麼是「正確」的方式來做這樣的工作?

public class Derived extends Super 
{ 
    public Derived(int arg) 
    { 
     if (some_condition_1) 
      super(); 
     else if (some_condition_2) 
      super("Hi!"); 
     else if (some_condition_3) 
      super(new int[] { 5 }); 
     else 
      super(arg); 
    } 
} 
+0

什麼是「some_external_condition」的一些例子嗎?看起來好像任何這樣的情況必須在* super之後被檢查*。 – ggreiner 2012-02-10 23:09:38

+0

@ggreiner:實際上它不一定是外部的。我稍微改變了這個例子。它可以簡單地基於用戶的參數(這可能更適合作爲枚舉而不是整數,但這有點不相關)。 – Mehrdad 2012-02-10 23:11:12

回答

4

是的,@JohanSjöberg說。

也看起來你的例子是高度設計的。有沒有什麼神奇的答案可以清除這個混亂:)

通常,如果你有這樣一堆構造函數,將它們重構爲四個單獨的類是一個好主意(一個類應該只負責一種類型的事物)。

+0

是的,我不知道......這是我的一個朋友顯然遇到的問題,而不是我遇到的問題。完全同意第三段。 +1 – Mehrdad 2012-02-10 23:21:31

+3

我在實際代碼中遇到了這個問題:爲android編寫向後兼容的代碼:LinearLayout具有不同的構造函數,具體取決於android.os.Build.VERSION.SDK_INT的值。 – Timmmm 2012-11-01 11:18:52

1

super必須在構造函數中的第一條語句,因此你的樣品中的邏輯是無效的。

正確的方法是在您的擴展類中創建相同的 4個構造函數。如果您需要驗證邏輯,則可以使用例如builder模式。您也可以按照@davidfrancis的意見中所建議的將所有構造私有並提供靜態工廠方法。例如,

public static Derived newInstance(int arg) { 
     if (some condition) { 
     return new Derived(arg); 
     } 
     // etc 
} 
+0

那麼你如何檢查條件? – Mehrdad 2012-02-10 23:10:26

+1

@Merhdad,你把它留給構建對象的類。如果你想執行特定的檢查,這可以是例如「builder」。 – 2012-02-10 23:11:18

+0

或者對一個接受條件的類有一個靜態方法,檢查它,然後實例化並返回該類的一個實例。 Derived上的「額外」構造函數在這種情況下可能是私有的。這不一定是一種方式,只是另一個配方。 – 2012-02-10 23:12:42

0

不能這樣做super必須是構造函數中的第一條語句。

正確的選擇是構建器類,並且在超類的每個構造器的派生類中都有一個構造器。

例如。

Derived d = new DerivedBuilder().setArg(1).createInstance(); 

public class DerivedBuilder { 

    private int arg; 

    // constructor, getters and setters for all needed parameters 

    public Derived createInstance() { 
     // use appropriate constructor based on parameters 
     // calling additional setters if need be 
    } 
} 
4

使用靜態工廠和四個私有的構造。

class Foo { 
public static Foo makeFoo(arguments) { 
    if (whatever) { 
     return new Foo(args1); 
    } else if (something else) { 
     return new Foo(args2); 
    } 
    etc... 
    } 
    private Foo(constructor1) { 
    ... 
    } 
    ... 
} 
1

你不能這樣做,但你可以調用您的類的代碼做到這一點:

 if (some_condition_1) 
      new Super(); 
     else if (some_condition_2) 
      new Super("Hi!"); 
     else if (some_condition_3) 
      new Super(new int[] { 5 }); 
     else 
      new Super(arg); 
相關問題