2015-05-11 238 views
3

我有一個抽象類Specie,然後是類動物擴展物種,然後是我的動物類(例如羊)。在動物中,我有一種方法來檢查兩個物體是否在地圖上的相同位置,如果它們是相同的類型(例如羊和羊)。Java創建新對象

如果是,它會創建另一隻綿羊。我有與 問題,我想這樣的事情

Specie new_specie = this; 

而且我有一個副本consturctor在我的羊類

 public Sheep(Sheep new_sheep){ 

    this(new_sheep.get_x(),new_sheep.get_y(), new_sheep.get_img()); 
} 

然後將其保存到其中包含的所有對象的數組

species[speciesAmount] = new_specie; 

但它只是保存在數組中的兩個元素相同的對象

species[0] 
species[2] 

相同的對象。有任何想法嗎?

但是還有一個問題,我將有更多類型的動物(公式狼)的,我不能做

new Specie(this) 

,因爲它是一個抽象類。

如何讓它調用正確的構造函數?

編輯。我解決了它,我使用了clone()方法。

+2

公羊(羊new_sheep){ 您是否看到這個問題?基本上,你需要有一個羊實例,以便能夠創建一個... – Stultuske

+0

但還有另一個問題,我將有更多類型的動物(方程式狼),我不能做 new Specie(this) 因爲它是一個抽象類,如何使它調用合適的consturcotr? – Cardano

+1

新的Specie(this)有點廢話imho,只要使用克隆方法,如果你需要類似的東西。 – Stultuske

回答

3

Specie new_specie = this;只會創建一個名爲new_specie的新參考,並讓它指向與this相同的對象。因此species[speciesAmount] = new_specie;將分配相同的引用數組條目(這本身就是一個參考)。

您的代碼根本不會調用複製構造函數。與C++在Java中調用拷貝構造函數必須是這樣的:

Specie new_specie = new Sheep(this); 

順便說一句,你可能想看看進入Clonable接口這是爲了提供對象拷貝。

更新:關於你的第二個問題,解決方案取決於你想達到什麼。如果您只是希望在其中有兩個物種的場地上存在具體物種的副本,則可以比較兩個物種的類別(使用getClass()方法)或使用equals()檢查相等性(取決於您如何定義該物種,它往往不止是平等的課程)。

然後,你基本上只是打電話Species new_species = species_on_field.clone()並獲得克隆該領域之前的東西。

另一種選擇可能是使用工廠模式或基於該領域當前物種種類的原型。儘管如此,我會留下這些給你看。

2

在Java中,您無法使用任務調用複製構造函數。你必須打電話給它!

species[0] = new Sheep(this); 
1

您可以通過比較其類,如種類比較:

if (specieA.getClass() == specieB.getClass) { 

然後,你的下一個步驟是創建一個新的物種。在運行時,您可以使用反射來訪問這些信息。這是不是真的美麗的東西,但有時無法避免(例如,你不希望創建一個開關的情況下,每種):

Class<?> clazz = specieA.getClass(); 
    Specie newSpecie = clazz.getConstructor(clazz).newInstance(specieA); 
} 

這看起來對specieA的類的構造函數(名爲clazz中這裏)接受一個clazz實例作爲它的輸入參數。這樣你就可以克隆任何東西(當然它有一個拷貝構造函數)。如果沒有,則會拋出異常(您需要嘗試捕獲)。