2012-05-09 53 views
3

我正在嘗試建立一個抽象類。我想確保任何子類都有一個列舉其可能操作的枚舉。抽象類和枚舉

例如,Foo是一個抽象類。

Fee extends Foo and can... 
    TALK 
    WALK 
    SLEEP 

Bar extends Foo and can... 
    SIT 
    STARE 

我想給父類的字段,並讓子類用它能夠執行的操作填充枚舉。我會如何處理這個問題?

例如,如果我在一個類中定義一個枚舉,給它一些通用的動作,它會被傳遞給一個子類,並且子類可以擴展枚舉嗎?這可能是另一種選擇。

回答

4

我不知道我的辦法同意,但你可以做

enum CanDos { 
    TALK, 
    WALK, 
    SLEEP, 
    SIT, 
    STARE 
} 

然後類可以有

abstract class Foo { 
    abstract Set<CanDos> getCanDos(); 
    //or 
    abstract boolean can(CanDos item); 
} 

你也可以使用一個EnumSet的高效存儲能力。

如果你正在尋找的是正確的事情提供一組枚舉(如你提到的父抽象類中的字段),那麼我認爲EnumSet<CanDos>是你的人。在這種情況下

abstract class Foo { 

    private final Set<CanDos> candos; 

    protected Foo(Set<CanDos> candos) 
    { 
    this.candos = new EnumSet<CanDos>(candos); 
    } 

    public boolean can(CanDos item) { 
    return candos.contains(item); 
    } 
} 

或者,也可以完全避免抽象類(或至少不必這樣做參見例如this questionthis one)。備受推崇的書Effective Java建議「Prefer interfaces to abstract classes」。

要做到這一點,而不是

enum CanDos { 
    TALK, 
    WALK, 
    SLEEP, 
    SIT, 
    STARE 
} 

public interface FooThatCanDo { 
    boolean can(CanDos item); 
} 

如果你真的認爲有一個共同繼承根(你應該好好想想)值,那麼你可以提供一個抽象基實現如上圖所示,並宣佈它implements FooThatCanDo

+0

我認爲我想要一個抽象類,因爲我有一個標準的方式來做到每這些事情(即最後一個方法'doStuff(CANDO doThis)')。這聽起來像個好主意嗎? – gobernador

+0

@gobernador:我會先看看指導。使用抽象類有很好的理由,但有更好的理由可以避免。我建議閱讀主題http://my.safaribooksonline.com/book/programming/java/9780137150021/classes-and-interfaces/ch04lev1sec6上的Effective Java部分,或者至少是這個問題:http://stackoverflow.com/questions/56867/interface-vs-base-class,並詢問標準是否適用於您。 – andersoj

+0

@gobernador:你也可以擁有兩全其美的世界 - 編寫一個抽象類,並將其包含在子類中,而不是從繼承類繼承。這可能是一個很好的中間立場,可以讓你擁有共同的代碼,而不是固定不便的繼承樹。如果你寫更多關於你上面的具體問題,可能會提供更多。 – andersoj

0

我不認爲一個枚舉是你在找什麼,至少不是直接。也許你可以使用BitSet

class Base { 
    private static EnumSet actions; 

    public EnumSet getActions() { return actions; } 
} 

class Derived extends Base { 
    private static EnumSet actions; 

    @Override 
    public EnumSet getActions() { 
     return new EnumSet(actions).addAll(super.getActions()); 
    } 
}