2017-04-10 50 views
-1

我正在創建一個程序,其中有一個動物類,並擴展了「羊」和「牛」類。 在我的程序中,我還有一個'Farm'類,它將在調用'generate()'時創建一個新的動物。當我初始化該程序時,每個農場都有一個特定的動物來生成。從更普通的類生成對象

我可以想出幾種方法來做到這一點,但沒有一個看起來特別好。我想出了一個辦法是有我的課列明這樣的:

public class Farm { 
    public Animal typeOfAnimalToSpawn; 

    public Farm(Animal a) { 
     typeOfAnimalToSpawn = a; 
    } 

    public void generate() { 
     typeOfAnimalToSpawn.spawnMe(); 
    } 
} 

public abstract class Animal { 
    public abstract void spawnMe(); 
} 

public class Sheep { 
    public void spawnMe() { 
     new Sheep().create(); 
    } 

    public void create() { 
     // Spawn this sheep onto the field (By making it visible or something) 
     // Do whatever needs done when a sheep arrives 
    } 
} 

這似乎瘋狂複雜難懂的東西,我只能假設有一個簡單而優雅的解決方案。在這種情況下,我實際上使用羊作爲類型(對於農場)和對象(對於創建時)。最重要的是,它讓我誤以爲新的Sheep()實際上並沒有創建一隻綿羊,並且只有在調用create()之後纔會發生任何事情。它也不適合存放整個動物的一個實例,只是作爲農場產生未來動物的類型。

這將是很容易簡單地對每一個類型的動物農場:

public abstract class Farm { 
    public abstract generate(); 
} 

public class SheepFarm extends Farm { 
    public void generate() { 
     new Sheep(); 
    } 
} 

public class Sheep { 
    public Sheep() { 
     // Do whatever needs done when a sheep arrives 
    } 
} 

這是漂亮和整潔的表面上,但需要額外的,完全無用類爲每一個新動物加入到節目。不完全理想。

還有另一種方式,有反思,但我不願意使用它,因爲我確信有一些更明智的做事方式。

所以,我的問題是,處理這種情況的最佳方式是什麼,並且比上述解決方案有更簡單的方法嗎?

我完全自學成功,所以我不知道做事情的正確方法,不得不用Google爲自己解決問題,但在這裏我完全失敗了;我不知道在哪裏甚至可以開始尋找關於常見編程範例的信息,當然,除了維基百科,它並不完全符合「學會編寫整潔的代碼」教程。

如果我的問題脫落模糊甚至降權荒謬的,請你只問我澄清。

+2

我甚至無法在這裏找到問題。 –

+0

完全是我的錯。忘了問什麼。我的問題是:什麼是接近的情況下最好的辦法,例如這個,有沒有做的事情比我已經張貼上述方案中的一個更簡單的方法? – Oberdiah

+0

我不是對問題的陳述清楚這裏,你爲什麼不能簡單地做同樣的事情在'Sheep'類的內部選項1激起你正在做的選項2? – developer

回答

0

,我會去了解它的方法是使用泛型類型Farm(但是,你必須消除對Animal類抽象標識符):

public class Farm<E extends Animal> { 

    private E e; 

    public Farm() { 
     this.e = (E) new Animal(); 
    } 

    public void generate() { 
     e.spawnMe(); 
    } 

} 

如果你不熟悉與泛型類型,我肯定會研究它們!

+0

這真的很棒!泛型類型正是我正在尋找的!儘管如此,我仍然感到困惑,因爲在農場實際生成一隻綿羊之前,這仍然需要使用'new Sheep()',迫使綿羊的構造函數代碼移至spawnMe(); – Oberdiah

+0

@Oberdiah是的,不幸的是我不認爲有可能使用抽象工廠模式來創建不同類型的子對象,但泛型類型將是一種可行的方式! –

+0

因此,通常的做法是,推薦將大部分初始化代碼移動,比如添加到實體列表並將渲染設置爲單獨的方法,如createMe()? 下面有人發佈了一些關於'新T()',這將是很好,但不可能的原因很明顯。 – Oberdiah

0

您的第一個解決方案似乎非常高效。我認爲這將是最好的方式去做,因爲你可以輸入Farm sheepfarm = new Farm(new Animal...)。祝你好運:)