指定抽象方法的参数必须是枚举

时间:2012-03-22 18:38:26

标签: java enums abstract-class

我正在用Java编写一个抽象类,我想把我的一个抽象方法的参数作为一个枚举,所以我得到了以下内容。请注意,只有子类才能知道它可以具有哪些可能的状态。 (请原谅人为的例子)

public abstract class StateTracker {
    public abstract boolean isInState(???????? state);
}

什么是?????????问题在于:

  • 理想情况下,它将是一个名为StateEnum的抽象枚举,它没有实例,StateTracker的客户端可以创建自己的具体StateEnums。但我们不能在Java中做任何类似的事情。
  • 我可以把它变成一个接口,但是我无法确保子类将它实现为枚举,这就是目标。
  • 我可以将其更改为 Enum< ? > 即可。所以我尝试了,在我的子类中,我做了类似的事情:

    public class MyStateTracker extends StateTracker {
    
        public enum MyState {
             BADSTATE_1, BADSTATE_2
        }
    
        @Override
        public boolean isInState(?!?!?!?! state) {
             // TODO Auto-generated method stub
        return false;
     }
    
    }
    

现在是什么?!?!?!?!以下是可能性:

  • MyState。这不会编译,因为它不认为我重写了抽象方法。
  • 枚举。同样的问题。

如何确保具体类使用emum?

3 个答案:

答案 0 :(得分:4)

这取决于您是否希望能够询问StateTracker是否处于由不同enum类型声明的状态。

如果要锁定状态以便只能查询某种类型enum的给定状态跟踪器,请创建一个通用类型:

interface StateTracker<S extends Enum<S>> {
  boolean isInState(S state);
}

final class MyStateTracker implements StateTracker<MyStateTracker.MyState> {
  enum MyState { S1, S2 };
  private MyState state;
  ...
  @Override
  public boolean isInState(MyState state) {
    return state == this.state;
  }
}

如果您有几种enum类型定义如下状态:

enum MyState { S1, S2 }
enum YourState { S1, S2 };

...并且您希望能够StateTracker询问它是否处于任何状态(由任何enum定义),除非您还为您声明了State标记界面enum要实现),然后创建一个通用方法:

interface StateTracker {
  <S extends Enum<S>> boolean isInState(S state);
}

答案 1 :(得分:3)

class StateTracker<E extends Enum<E>> {
  public abstract boolean isInState(E state);
}

答案 2 :(得分:1)

你可以使用泛型来实现这一点,Java的枚举都是隐式扩展java.lang.Enum

abstract class StateTracker<T extends Enum<?>> {
    public abstract boolean isInState(T state);
}

enum MyState {
    State_1, State_2
}

class State extends StateTracker<MyState>
{
    private MyState currentState = MyState.State_2;

    @Override
    public boolean isInState(MyState state)
    {
        return state.equals(currentState);
    }
}

public class TestEnum
{
    @Test
    public void testIsInState()
    {
        State state = new State();
        Assert.assertFalse(state.isInState(MyState.State_1));
        Assert.assertTrue(state.isInState(MyState.State_2));
    }
}

//This won't compile, so the generic-type must be an Enum
/*
class State2 extends StateTracker<String> //<-- Bound mismatch: The type String is not a valid substitute for the bounded parameter <T extends Enum<?>> of the type StateTracker<T>
{
    @Override
    public boolean isInState(String state)
    {
        // TODO Auto-generated method stub
        return false;
    }   
}
*/