调用接口方法时避免向下转换

时间:2014-10-06 17:41:23

标签: java

好的,我有一个愚蠢的时刻。

我希望能够做到这样的事情

class Example {
    public State currentState;
}

interface State{}

interface StateCallbacks
{
    public void onState(IdleState state);
    public void onState(ContactingState state);
    public void onState(SuccessState state);
    public void onState(FailedState state);
}

并且可以调用onState(exampleInstance.currentState))并调用正确的方法。

现在我知道为什么不能这样做,因为没有人知道onState方法会存在State的所有无限可能子类。

我的问题是什么是在没有instanceOf运算符的情况下实现这样的事情的好方法。例如,我可以只包含onState(State)方法,但实现者最终会使用instanceOf

这个想法是View对象将实现回调接口并根据传递的状态放置视图操作逻辑。每个州都可能有复杂的元数据相关联。

AFAIK可以使用支持事件和/或订阅者继承的事件总线来完成,但只能通过这些事情如何工作的性质而且EventBus不关心是否没有定义处理特定事件的事件处理方法,不像我们的朋友编译器。

我知道这是一个简单的问题,但问题是,我也很简单。

非常感谢任何建议:)

2 个答案:

答案 0 :(得分:7)

通常使用visitor pattern解决此问题。

您按如下方式实施:

interface State {
    void accept(StateCallbacks visitor);
}

然后在所有State.accept实现中执行visitor.onState(this),因此例如IdleState看起来如下:

public class IdleState implements State {
    ...
    void accept(StateCallbacks visitor) {
        visitor.onState(this);
    }
}

(请注意,您在访问者模式中称为StateCallbacks的内容通常称为StateVisitor。)

然后,您可以使用

调用正确的方法
exampleInstance.currentState.accept(new StatePrinter());

如果你想对当前状态进行一些自定义打印。

答案 1 :(得分:1)

执行此操作的最佳方法是反转控制并使onState由子类而不是回调类实现。

这样的事情:

class Example {
    public State currentState;
}

interface State{
  public void doOnState();
}

abstract class StateCallbacks
{
    public void onState(State state){
      state.doOnState();
    }
}