package example; import java.awt.Point; public interface Thing { public enum MovingState { MOVING_LEFT,MOVING_UP,MOVING_RIGHT,MOVING_DOWN } public void setNewPosition(MovingState state); public Point getPosition(); }
和一个实现类:
package example; import java.awt.Point; public class ThingImpl implements Thing { public enum MovingState { MOVING_LEFT (-1,0),MOVING_UP (0,-1),MOVING_RIGHT (1,MOVING_DOWN (0,1); private int x_move; private int y_move; MovingState(int x,int y) { x_move = x; y_move = y; } public int xMove() { return x_move; } public int yMove() { return y_move; } } private Point position; public void setNewPosition(MovingState state) { position.translate(state.xMove(),state.yMove()); } public Point getPosition() { return position; } }
这个想法是让ThingImpl中的MovingState从Thing界面扩展MovingState(从而将MoveState的实际实现与界面分开).
这不起作用 – ThingImpl中的MovingState枚举会影响接口中的定义,而不是扩展它,然后编译器抱怨ThingImpl不是抽象的,并且不会覆盖Thing中的抽象方法setNewPosition(Thing.MovingState).
有没有实际的方法来做我想要实现的?还是Java根本没有这种能力?
解决方法
让你的字段在枚举中最后记住,他们不应该被触动.
以这种方式,任何希望使用Thing界面的内容都必须使用界面中定义的枚举 – 您的问题是您有效地定义了两次,但是它应该在界面上(这只会被使用对于此接口)或公共级枚举Java文件(使用公用枚举而不是公共类).如果您的界面以外的其他功能可以合理地期望使用它,您将会成为一个公开枚举 – 在我看来,Map.Entry是一个错误的嵌套界面,因为其他类可用于映射外部的键/值对,因此它应该是它自己的界面,但我们必须生活在它:(
The idea is to have MovingState in ThingImpl extend MovingState from the Thing interface (thus separating the actual implementation of MovingState from the interface).
我不认为这是真的你的想法 – 我认为你在Thing的界面上指定的行为很好,你真的不想触摸MovingState枚举,因为它是好的.但是,如果您认为需要使用MovingState的不同实现,则可以实现名为MovingState的接口,从而可以重命名您的枚举DefaultMovingState.这是你的选择.