2010-05-03 85 views
1

我想創建一組共享許多常見行爲的類。當然,在OOP中,當你認爲自動思考「帶有子類的抽象類」時。但是我希望這些類所要做的事情是每個類都有一個靜態的類實例列表。該列表應該在類中作爲一個單例。我的意思是每個子類都有一個單身人士,而不是他們分享一個。 「單身」到那個小類,不是一個真正的單身人士。但如果它是靜態的,我該如何繼承它?我如何製作一個單身家庭?

當然

像這樣的代碼將無法正常工作:

public abstract A 
{ 
    static List<A> myList; 
    public static List getList() 
    { 
    if (myList==null) 
     myList=new ArrayList<A>(10); 
    return myList; 
    } 
    public static A getSomethingFromList() 
    { 
    List listInstance=getList(); 
    ... do stuff with list ... 
    } 
    public int getSomethingFromA() 
    { 
    ... regular code acting against current instance ... 
    } 
} 
public class A1 extends A 
{ 
    ... 
} 
public class A2 extends A 
{ 
    ... 
} 

A1 somethingfromA1List=(A1) A1.getSomethingFromList(); 
A2 somethingfromA2List=(A2) A2.getSomethingFromList(); 

每個子類的列表中的內容會有所不同,但所有的代碼在名單的工作將是相同的。

上述代碼的問題是,我只有一個列表的所有子類,我想爲每個。是的,我可以複製代碼來在每個子類中聲明靜態列表,但是我還必須複製添加到列表中的所有代碼並搜索列表等,這相當於破壞了子類化的目的。

有關如何在不復制代碼的情況下執行此操作的任何想法?

更新

澄清BlueRaja,也許別人,讓我成爲一個更具體一點什麼,我試圖做的。

我有一些需要類似行爲的狀態和代碼。它們就像枚舉一樣,我希望爲每個可能的代碼狀態提供類型安全的實例,但是它們有多個集合,所以我不能只爲它們製作一個枚舉。

因此,例如我有訂單狀態,它具有按順序,發貨,收到的值和一些特殊值。我有物品類型,商品與服務的價值。我有股票與習俗。等

如果這就是它,我只是爲每個枚舉。但是,我還需要其他行爲,例如通過文本值查找對象的能力,例如,當我們從數據庫中讀取它時;建立一個下拉列表,通過文字描述列出所有的選擇;等等。據我所知,我不能用枚舉來做這件事,因爲我有幾組代碼,每個代碼都有我想要繼承的常見行爲,並且我不能繼承一個枚舉。將所有代碼放在一個枚舉中會放棄一個代碼相對於另一個代碼的類型安全性,也沒有證明爲特定代碼類型收集值列表的現成方法。

+2

不要在對象orietented世界中使用靜態持有狀態,這只是錯誤的。 – 2010-05-03 13:53:10

+2

不要使用單例,對靜態數據要非常小心。比繼承更喜歡構圖。 真的,你提到的幾乎沒有什麼是真正的「良好的面向對象」。 – jalf 2010-05-03 14:00:32

+0

好的。所以我有一組給定子類的實例,並且我需要維護一個所有這些實例的列表以供搜索,構建下拉列表等。好的,我可以創建一個包含列表的(非靜態)對象。但只有一個列表纔有意義。那有什麼好處呢?如果我用不同的列表創建兩個對象,那麼有些事情是錯誤的。如果沒有單身人士,你會如何解決問題? – Jay 2010-05-03 16:48:45

回答

5

您可以在父類中使用static Map<Class, YourClass> = new ConcurrentHashMap<..>()並使用該映射來添加/檢索實例。

雖然如此大的依賴單身人士聽起來像一個糟糕的設計 - 你應該儘量避免它。

+0

這個問題的答案是:子類中的靜態如何從HashMap中抽取適當的條目?我看到這樣做的唯一方法是將靜態放在超類中,並將類名作爲參數傳遞,如「A1 a1 =(A1)A.getSomethingFromA(A1.class)」。可以,但有點尷尬。你有沒有更簡單的方法? – Jay 2010-05-04 01:30:34

1

What is so bad about singletons?

編輯:一個問題的回答後: 你說「我要創建一組共享很多共同行爲的類」 - 這對我來說,不建議「與子類的抽象類完全「,因爲抽象類沒有行爲。它提出了一個實現常見行爲的單獨對象,以及許多聚合該單獨對象的類。

+0

好的。那麼如果沒有一個單身人士,你會如何解決這個問題? – Jay 2010-05-03 16:37:00

+0

你說「我想創建一系列共享許多共同行爲的類」 - 對我來說,*不會*提供「具有子類的抽象類」,因爲抽象類沒有行爲。它提出了一個實現常見行爲的單獨對象,以及許多聚合該單獨對象的類。 – 2010-05-04 07:15:49

0

從它的聲音,你真正想要的是一個具有自定義屬性的枚舉類和behaviours。有關Java中枚舉的強大功能的示例,請參閱here

+0

是的,這是真的,我想要的東西就像一個精心製作的枚舉。但是我想要數十個課程,並且有相同的闡述。據我所知,我不能繼承一個枚舉。所以是的,我可以通過使用相同代碼製作一大堆枚舉來實現這一點。但是複製粘貼代碼是一個維護噩夢。除非有一種方法來枚舉枚舉,否則這不會爲我在這裏削減。 – Jay 2010-05-03 14:25:31

+0

@Jay:不,你想要一個* single *枚舉類,不涉及子類。現在你使用類的每件事實際上都是一個枚舉值。每個「類」的自定義行爲實際上是一個抽象枚舉方法的實現,它針對每個枚舉值。與其他任何課程一樣,共享的任何東西都只是枚舉的一部分。不會涉及複製/粘貼 - 你所描述的情況完全是Java的強大枚舉。 – 2010-05-03 14:30:22

+0

我認爲你誤解了我的要求。 (或者我誤解了你。)我將原始問題更新爲更具體,也許這會澄清。 – Jay 2010-05-03 16:26:30

0

我會想一個工廠方法:

public class Factory { 
    private static final A1 a1Instance = new A1(
      Collections.synchronizedList(new ArrayList<something>(100))); 
    private static final A2 a2Instance = new A2(
      Collections.synchronizedList(new ArrayList<something>(100))); 

    public static A getA1() { return a1Instance; } 
    public static A getA2() { return a2Instance; } 
} 

你一個不會需要所有這些static方法了,當然。

0

如果你需要一個單獨的功能,並在同一時間想繼承的好處,你應該考慮依賴注入框架如春PicoContainer的。即使您的應用程序非常小,使用框架管理依賴關係仍然會讓您的生活更輕鬆。