当前位置: 首页 > 知识库问答 >
问题:

可选回调[重复]

鲁涵意
2023-03-14

我有接口

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

有没有可能把方法变成可选的?

共有3个答案

邢永安
2023-03-14

没有。

使用虚拟实现并在需要时重写。

浦泳
2023-03-14

不,这在Java是不可能的。

看看这个问题,它得出了同样的结论:Java接口中的可选方法

宗苗宣
2023-03-14

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

您将创建一个抽象类,用空的默认实现实现接口的可选部分,如

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 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
        }
    }
}

通过这种方式,您可以自由选择要实现的接口类型,并且调用代码会检查您是否希望获得回调。例如,如果您注册(new UserResponseCallbackFull(){…})如果要注册(new UserResponseCallbackBase(){…}),您将收到关于启动()的通知 你不会的。

这种技术在Android中与ComponentCallbacks2一起使用,你可以通过Context#registerComponentCallbacks(ComponentCallbacks)注册组件回调,它同时接受一个“简单的”ComponentCallbacks和扩展版本,并检查你给它的类型。

 类似资料:
  • 我已经做javascript有一段时间了。然而,我对Angular 2还比较陌生,所以我对可观测的东西几乎一无所知。当我读到对可观测事物的描述时,它们听起来很像我已经知道的回调。当我问谷歌时,有回调和promise之间的比较,也有promise和可观察之间的比较。然而,我找不到回调和可观察之间的任何比较。 回调和可观察之间有什么区别?

  • 是否有任何方法可以从NamedParameterJdbcTemplate返回可选的? 我的查询有时会返回空。所以我想要漂亮的方法来检查空。我不想做尝试捕捉空结果数据访问异常,因为这个有点丑。

  • 编译错误->[无法推断flatMap(函数>)的类型参数]

  • 我试图模拟一个对象,该对象返回一个带有Mockito的Java可选对象: 当被调用,它返回。 我希望方法返回 返回的任何原因? 方法如下: 以下是Junit:

  • 我试图获得以下行为: python test.py= 当我使用 但是,如果我添加,试图强制强制强制转换为布尔值,它就会中断。在这种情况下 实际上最终存储。怎么回事??

  • 为什么这段代码会抛出异常?为什么它还要去“奥雷尔斯”分店? 这是因为某种怪异的处决令吗?那么在计算orElse分支之前没有设置第一个可选项的值?