2011-10-26 46 views
4

我正在嘗試完成一個項目,儘管我已經嘗試過了,但我似乎無法做到這一點。這裏的枚舉:如何在Java中使用枚舉拷貝構造函數?

public enum Symbols { 
    /** 
    * The Seven 
    */ 
    SEVEN(12,"images/seven.jpg"), 
    /** 
    * The Watermelon 
    */ 
    WATERMELON(10,"images/watermelon.jpg"), 
    /** 
    * The Orange 
    */ 
    ORANGE(8,"images/orange.jpg"), 
    /** 
    * The Plum 
    */ 
    PLUM(6,"images/plum.jpg"), 
    /** 
    * The Lemon 
    */ 
    LEMON(4,"images/lemon.jpg"), 
    /** 
    * The Cherry 
    */ 
    CHERRY(2,"images/cherry.jpg"); 

    private int payout;    // Symbol payout value 
    private BufferedImage image; // Symbol image 
    private String icon;   // Symbol file name 

    /** Constructor - Payout must be positive and even, file name must not be null 
    * @param payout - Symbol payout amount 
    * @param icon - Symbol image file name 
    */ 
    Symbols(int payout, String icon){ 
     this.payout = payout; 
     this.icon = icon; 
     loadImage(icon); 
    } 

    /** Copy Constructor - Symbol must not be null 
    * @param s - A single symbol 
    */ 
    Symbols(Symbols s){ 
     payout = s.payout; 
     icon = s.icon; 
     loadImage(icon); 
    } 

現在我可以進入主並創建一個名爲「S」這樣的符號:

Symbols s = Symbols.CHERRY; 

但我有麻煩的「S」副本使用複製構造函數給出:

Symbols t = Symbols(s); 

如果我試圖做到這一點,我得到的錯誤:「該方法符號(符號)是未定義的類型符號。

謝謝

回答

0

枚舉是不正常的類。你不能手動構建它們。枚舉「類」本身基本上是一個「抽象」類。每個值都是作爲枚舉「類」的一個單獨的特定子類實現的。

4

那麼你需要把它公開,但它仍然不會工作。 Java中沒有拷貝構造函數;你不能'新'一個枚舉,這是下一個錯誤;無論如何,Java會竭盡全力確保每個JVM只有每個枚舉值的一個副本。你認爲你究竟需要一個拷貝構造函數

解決方案:

Symbols s = Symbols.CHERRY; 
Symbols t = s; 
+0

那麼如果你定義了它們(他完成了),那麼就有複製構造函數。 –

+0

@MarkPeters,但編譯器不會*使用*它們,除非你自己調用它們。例如,他給出的代碼不會編譯,如果他寫了't = s;'編譯器不會自動調用複製構造函數。我不稱之爲複製構造函數。只是一個構造函數。 – EJP

+0

你是對的,它不是一個複製構造函數,因爲有隱式調用它的語法(就像我認爲C++會)。但我認爲調用一個將其自己的類的實例作爲「複製構造函數」的構造函數仍然是常見做法。 –

2

枚舉應該是一個不變的集 - 你不應該是能夠結交新朋友。而構造函數被強制執行爲私有(即使沒有標記爲這樣)。

由於它們是不可變的,你總是應該保證,如果你有一個Symbols.CHERRY對象的實例,它總是相同的實例,所以你可以做一些事情,比如測試對象等價而不是等於 - 即你因爲如果你有CHERRYs他們保證是同一個對象可以做的

if (symbol == CHERRY) 

代替

if (symbol.equals(CHERRY)) 

這更意欲在Typesafe Enum模式的強制版本:

public class Suit { 
    private final String name; 

    public static final Suit CLUBS =new Suit("clubs"); 
    public static final Suit DIAMONDS =new Suit("diamonds"); 
    public static final Suit HEARTS =new Suit("hearts"); 
    public static final Suit SPADES =new Suit("spades");  

    private Suit(String name){ 
     this.name =name; 
    } 
} 
2

好,構造函數只被調用,當你調用new關鍵字:

Symbols t = new Symbols(s); 

沒有new它認爲你試圖調用名爲Symbols的方法。

但這在這種情況下是不相關的,因爲你不能在常量定義之外實例化枚舉。如果可以的話,它不會是枚舉。

讓我們來看看爲什麼你會想要想要有一個枚舉的副本。如果你需要一個副本,這肯定是因爲你說這個枚舉是有狀態的,這不可能是真實的。枚舉必須是不可變的。而且由於它們必須是不可變的,你可以在任何地方共享實例。

0

枚舉是不允許創建新對象的類。所以你的Symbol類(枚舉)只有六個實例。您不能調用枚舉構造函數,但可以爲這六個實例創建引用的副本。

Symbols s = Symbols.CHERRY; //Get a copy of reference for instance CHERRY 

另一方面,如果您想在Java中使用高構造函數,則需要使用關鍵字「new」。

1

您使用枚舉是這樣的:

public enum Symbols { 
    SEVEN(12,"images/seven.jpg"), 
    WATERMELON(10,"images/watermelon.jpg"); 

    private int payout; 
    private String icon; 

    Symbols(int payout, String icon){ 
     this.payout = payout; 
     this.icon = icon; 
    } 

    public int getPayout(){ 
     return this.payout; 
    } 

    public String getIcon(){ 
     return this.icon; 
    } 
    public static void main(String[] args){ 
     System.out.println(Symbols.SEVEN.getPayout()); 
    } 
} 

其他的答案了,爲什麼你不能有拷貝構造函數一個很好的解釋。基本上你的enum類的「實例」(SEVEN和WATERMELON)是不可變的,所以你不能在運行時指定任何其他的值,也不能創建新的值。