2013-08-17 49 views
2

假設我正在下棋。擁有Piece()的基類會更有效嗎?用每種類型的作品的子類。如何知道何時使用枚舉或子類?

或者,枚舉

enum Piece{ 
King, 
Queen, 
Knight, 
etc; 
} 

它也帶來了我到一個共同的問題,改進數據時,我有。

GameObjects 
Piece extends GameObjects 

我應該在這裏停下來聲明與他們各自的屬性的對象?

Piece King = new Piece("King",5,10); //just made up values, no significance. 

或進一步細化,並具有:

King extends Piece 

,然後處理王件的多態方式:

Piece king = new King("King,5,10); 

感謝

回答

1

多態性

這取決於在h你想要構建遊戲邏輯,但在抽象類Piece中定義公共行爲(方法)和屬性(字段)可能很有意義,然後讓每個子類實現抽象方法(或覆蓋默認方法)並設置值基於它們變化的方式的繼承字段。也許是這樣的:

public abstract class Piece { 
    protected int value; 
    public int getValue() { 
     return value; 
    } 
    public abstract boolean isValidMove(String move); 
    public void move(String move) { 
     //common logic here 
     doMove(move); 
    } 
    protected abstract void doMove(String move); 
} 

public class King extends Piece { 
    public King() { 
     this.value = 20; 
    } 
    public boolean isValidMove(String move) { 
     //specific king logic here 
    } 
    protected void doMove(String move) { 
     //more specific king logic 
    } 
} 

這將允許您使用多態來定義各個部分具有共同Piece API,而重要的差異是由每個具體類型的處理。

Piece king = new King(); 
//... 
if(king.isValidMove(move)) king.move(move); 

枚舉

枚舉允許你創建一組常見的類型,也可以定義行爲的優化單實例,但它們不支持首要/執行特定類型的行爲非常好,因爲您最終必須檢查當前實例在執行變體時的枚舉類型。當你真的需要遊戲的倍數(一個白色國王和一個黑色國王,8個白色棋子和8個黑色棋子)時,你最終還會遇到只有一個KINGPAWN實例的問題。

public enum Piece { 
    KING(20), 
    PAWN(1); 
    private int value; 
    private Piece(int value) { 
     this.value = value; 
    } 
    public int getValue() { 
     return value; 
    } 
    public boolean isValidMove(String move) { 
     switch(this) { 
      case KING: 
       //king specific logic 
       break; 
      case PAWN: 
       //pawn specific logic 
       break; 
     } 
    } 
    public void move(String move) { 
     if(this == KING) { 
      //king specific logic 
     } else if(this == PAWN) { 
      //pawn specific logic 
     } 
    } 
} 

因此,在這種情況下枚舉可能無法很好地工作。

0

如果實例存在受限和定義的編號,則使用枚舉。

在這種情況下,顯然有一個定義數量的片斷,所以使用枚舉。

請注意,枚舉可以像普通類一樣擁有方法,所以枚舉不必只是「值」,它們可以做東西。

我不會試圖太多塞進你的枚舉,而事實上我將它命名爲PieceType要清楚究竟意味着什麼,也許有一個類Piece這是一塊具有PieceType的情況下,一個位置(棋盤格)和一個顏色。

0

主要的區別在於,一組子類是開放式的:您或其他使用您的代碼的人可以在不破壞舊代碼的情況下創建新的子類。 枚舉是相反的:其他人不能將新項添加到您的枚舉中,即使您是代碼的維護者,如果不仔細檢查每一個switch-case語句,就不能添加新的枚舉常量。

因此,如果您不希望將新項目添加到集合中,請使用枚舉。否則使用子類。這並不意味着子類更好:如果你知道一組封閉選項,那麼你不應該使用子類。如果你這樣做,你會發現自己正在寫if (... instanceof ...)連鎖店!

如果使用枚舉你發現自己添加新case s到您的switch語句(或者你可以預見到),然後切換到子類。如果使用子類,則發現自己正在編寫instanceof鏈,然後切換到枚舉。