我有界面
public interface UserResponseCallback {
void starting();
void success();
void error(String message);
void finish();
}
是否可以使方法可选?
答案 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)
没有
使用虚拟实现并在需要时覆盖。