可选的回调

时间:2014-02-18 10:21:48

标签: android callback

我有界面

public interface UserResponseCallback {
    void starting();
    void success();
    void error(String message);
    void finish();
}

是否可以使方法可选?

3 个答案:

答案 0 :(得分:6)

非抽象类必须实现从接口或父类继承的每个抽象方法。但是你可以使用它来允许你只实现某些必需的部分,只要你可以忍受你不能再随意实现接口的事实。

您将创建一个抽象类,该类使用空的默认实现(如

)实现接口的可选部分
abstract class UserResponseCallbackAdapter implements UserResponseCallback {

    @Override
    public void starting() { /* nothing */ }

    @Override
    public void success() { /* nothing */ }

    @Override
    public void error(String message) { /* nothing */ }

    // finish() intentionally left out
}

您现在可以创建必须实现所需部分的子类,同时它们仍然可以实现可选部分。

class User {
    private final UserResponseCallback callback = new UserResponseCallbackAdapter() {

        @Override
        public void finish() {
            // must be implemented because no empty default in adapter
        }

        @Override
        public void starting() {
            // can be implemented
        }
    };

    void foo() {
        // can be used like every other UserResponseCallback
        CallbackManager.register(callback);
    }
}

此技术例如由AWT事件回调使用,例如MouseAdapter。一旦你多次使用回调,它就开始值得付出额外的努力,因为可选部分只需要实现一次而不是每次都实现。

您的下一个选项是将界面拆分为两个。您的概念问题是您的界面包含的内容超出了应有的范围,请比较Interface Segregation Principle。您可以将其拆分为两个或更多实际独立的接口,或者您可以使用可选的额外功能(如

)扩展所需的基本接口
interface UserResponseCallbackBase {
    // this is the only required part
    void finish();
}

interface UserResponseCallbackFull extends UserResponseCallbackBase {
    void starting();
    void success();
    void error(String message);
    void finish();
}

要使用这种分层回调,您可能会为管理回调的任何类添加一些智能,并让它根据它的类型检查回调是否需要某个回调。

例如

class CallbackManager {
    private List<UserResponseCallbackBase> mCallbacks = new ArrayList<UserResponseCallbackBase>();
    public void register(UserResponseCallbackBase callback) {
        mCallbacks.add(callback);
    }

    public void notifyStarting() {
        for (UserResponseCallbackBase callback : mCallbacks) {
            // check if callback is of the extended type
            if (callback instanceof UserResponseCallbackFull) {
                ((UserResponseCallbackFull)callback).starting();
            } // else, client not interested in that type of callback
        }
    }
}

通过这种方式,您可以自由选择要实现的接口类型,并且调用代码会检查您是否要进行回调。即如果您register(new UserResponseCallbackFull() {...}),我们会通知您starting(),如果您register(new UserResponseCallbackBase() {...}),则不会。{/ p>

此技术用于Android ComponentCallbacks2,您可以通过Context#registerComponentCallbacks(ComponentCallbacks)注册 - 它既需要“简单”ComponentCallbacks也需要扩展版本,并检查您提供的类型。< / p>

答案 1 :(得分:4)

不,这在Java中是不可能的。

看看这个得出相同结论的问题:Optional Methods in Java Interface

答案 2 :(得分:1)

没有

使用虚拟实现并在需要时覆盖。