2013-10-29 33 views
2

對不起,如果我的格式不好,首次在StackOverflow。 我有一組相同類型的水果類的所有擴展對象的FruitBuilder班,FruitBuilder包含了一組變量是這樣的:有沒有辦法強制方法使用不使用instanceof的子類構造函數?

public Apple redApple = new Apple(size, color, price); 
public Orange bigOrange = new Orange(size, color, price); 
public Pear greenPear = new Pear(size, color, price); 

,我有所謂的複製方法makeFruit,創建一個新的水果,並將其添加到一個ArrayList的水果,看起來像這樣:

public Fruit makeFruit(Fruit f){ 
    Fruit fruit = new Fruit(f.size, f.color, f.price); 
    fruits.add(fruit); 
    return fruit; 
} 

這工作得很好,只是它創建了一個新的水果,而不是所需要的子類,我可以把它通過使用一系列工作的instanceof檢查,然後逐個強制子類:

public Fruit makeFruit(Fruit f){  
if (f instanceof Apple){ 
     Apple apple = new Apple(f.size, f.color, f.price); 
     fruits.add(apple); 
     return apple; 
     //snip 
    } 
} 

有沒有更簡單的方法來做到這一點?

+0

你似乎是使用類作爲一個類型,你可以像'枚舉類型{蘋果,橘子,梨}'的屬性,只是有一個場,這和只有一個'水果'類。 –

+0

這是因爲每個子類都有不同的方法來覆蓋超類。 –

+1

我懷疑它們也可以是基於屬性的。 –

回答

2

你可以在水果類中創建一個抽象方法

public abstract Fruit copy() 

然後在每個子類中,如添加的具體實現對於蘋果類:

@Override 
public Apple copy(){ 
    Apple apple = new Apple(this.size, this.color, this.price); 
    fruits.add(apple); 
    return apple; 
} 
+0

爲什麼要採取你正在複製的「水果」?你可以有一個沒有參數的copy()方法,這樣你就可以執行'fruits.add(apple.copy())'。畢竟,在你的例子中是一個實例方法。 – Brian

+0

有效的一點。如果是類方法,則需要參數,在此示例中,僅複製實例值會更好。我會更新這個例子。 –

+0

這可能適用於我,聽起來像是我的問題的最佳解決方案。謝謝。 –

3

使用clone() - 它的設計出於這樣的目的:

public Fruit makeFruit(Fruit f) { 
    Fruit fruit = (Fruit)f.clone(); 
    fruits.add(fruit); 
    return fruit; 
} 

有幾種方法,使clone()工作你的類。最簡單的就是讓Fruit實施Cloneable

public class Fruit implements Cloneable { 
    ... 
} 

這是一個marker interface,所以你不需要實現任何方法。

+1

沒有抱歉,我忘了提及我需要淺拷貝而不是深拷貝,克隆是不行的。謝謝你:) –

+0

clone()'返回Object,你需要施放它。 –

+1

克隆不是深拷貝,它有幾個缺陷。 –

1

您可以使用反射:

public Fruit makeFruit(Fruit f) 
{ 
    Fruit fruit = f.getClass() 
        .getConstructor(int.class, int.class, int.class) 
        .newInstance(f.size, f.color, f.price); 
    fruits.add(fruit); 
    return fruit; 
} 

您需要處理的異常。

+0

聽起來相當不錯,我可能會使用另一個答案中提出的copy()方法,所以我不必處理不同的構造函數,但我會在將來考慮這一點。謝謝。 –

相關問題