2012-05-09 55 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()); 
    } 
}