我正在做一个非常愚蠢的ALife-esque应用程序,我将使用以下继承关系来创建以下类:
(摘要)Lifeform< - Plant
(摘要)Lifeform< - Animal
植物和动物有一些共同的状态,我希望这种行为能够在Lifeform中以rudamentary的形式存在。
abstract class Lifeform
{
public static enum State
{
IDLE,
DEAD
}
protected void someMethodSomewhere()
{
....
state = State.IDLE; // this to be recognized by inherited creatures
....
}
protected State state;
}
class Plant extends Lifeform
{
public Plant() { state=new Plant.State(); }
public static enum State extends Lifeform.State // (can't)
{
FEEDING,
REPRODUCING,
}
}
class Animal extends Lifeform
{
public Animal() { state=new Animal.State(); }
public static enum State extends Lifeform.State // (can't)
{
FEEDING,
FORAGING,
FLEEING,
GROUPING,
REPRODUCING
}
// elsewhere in some method
public void someMethod()
{
switch(state)
{
case IDLE: (...) // from Lifeform.State
case FEEDING: (...) // from Animal.State
case DEAD: (...)
....
}
}
}
在后来的(1.5+)java中是否有设施允许类似的内容,或者我最好将这种状态层次结构嵌入其自己的传统类中?
答案 0 :(得分:1)
您的名字为State
,这对我来说意味着您实际上正在使用状态机。我不会使用enum
来实际建模一个合适的状态机。
从您在问题中发布的州,它们也意味着有限的状态机。我认为你只是围绕这些enums
实现某种状态机作为最终结果,并且应该继续并从最终结束的地方开始。
我过去使用state machine compiler效果很好,只是简单地创建和管理状态转换。
Ragel看起来也是一个很好的解决方案。
在Java以enum
作为类型之前,我在IDE中使用了Type Safe Enum Pattern
模板来创建实际上更加丰富的语言结构实现。
它本质上只是一个带有final
个实例成员的Java类,以及一个private
构造函数和public final static
个实例。
我仍然会警告,由于一个很好的理由不允许延长enum
,并且试图解决它可能会让你更难以解决。
答案 1 :(得分:0)
以下是我多年来使用的解决方案,以防有人帮忙。我稍微改写了一下。
注意:它故意不实现价值支持。这不是一个很难改变,坦率地说,我不会使用它们,所以我把它拉了出来。我还从原来的古老版本重写了它。
注意:我主要在这里提供它,因为它包含toString()支持以从任何子类产生字段名称(无论您使用了什么)。
由于访问限制导致灾难性(执行结束)错误,我还指定了字段错误。您可以将其修改为您选择的任何异常处理,但我建议您保持原样。
package tgm.utils;
import java.lang.reflect.Field;
public abstract class InheritableEnum
{
protected InheritableEnum() {}
public String toString()
{
String returnStr = "Unknown InheritableEnum["+super.toString()+"]";
Field[] fields = this.getClass().getFields();
for (Field f : fields)
{
try
{
if (f.get(this) == this)
{
returnStr = f.getName();
break;
}
}
catch(IllegalAccessException e)
{
System.err.println("Illegal access on field["+f+"]");
e.printStackTrace();
System.exit(-1);
}
}
return returnStr;
}
}
然后你会同样使用它:
public class State extends InheritableEnum
{
public static final State DEAD = new State();
public static final State EATING = new State();
public static final State GROWING = new State();
}