我正在使用Google Web Toolkit,而且我在实现通用界面方面遇到了问题。我不熟悉泛型,在这里对其他人的代码进行升级。
这就是我想要做的:我希望有一个通用回调接口的实现来执行一些日志记录,然后将该实现子类化以处理特定的回调场景。
界面是这样的:
public interface AsyncCallback<T> {
void MethodFromAsyncCallback(T result);
}
抽象和具体的实现看起来像这样:
class CallbackBase implements AsyncCallback<Object> {
public abstract void doStuff(Object result);
public void MethodFromAsyncCallback(Object result) {
// IMPORTANT STUFF
// here are things I would like to do for all callbacks, hence the superclass.
// Then we do the subclass specific things.
doStuff(result);
}
}
class SpecificCallback extends CallbackBase
{
public void doStuff(Object result) {
Integer i = (Integer)result;
// do stuff with i
}
}
需要从
触发回调public interface MyServiceAsync {
public void DoSomeThing(AsyncCallback<Integer>);
}
然后这一切都在一个看起来像这样的电话中聚集在一起:
MyServiceAsync myService = (MyServiceAsync)GWT.create(MyServiceAsync.class);
myService.DoSomeThing(new SpecificCallback());
这就是我们遇到问题的地方!
当GWT.create()
实现我创建的接口时,它要求指定给AsyncCallback
的类型(匹配其他地方的类型,超出了这个问题的范围),因此{{1}一个整数而不是一个对象。这超出了我的控制范围。
它抱怨DoSomething(AsyncCallback<Integer>)
需要DoSomething()
。我正在给它一些继承自AsyncCallback<Integer>
的东西。我想用泛型,继承的概念有点破碎?
所以我的问题是:
要么我怎么能把这个放在一起,以便AsyncCallback<Object>
能够认识到DoSomething()
符合它的要求,
或如何构建SpecificCallback
和CallbackBase
之间的关系,以避免重复代码,但SpecificCallback
直接实现SpecificCallback
?
感谢。
答案 0 :(得分:10)
我认为您需要做的是像这样定义CallbackBase
:
abstract class CallbackBase<T> implements AsyncCallback<T> {
public abstract void doStuff(T result);
public void MethodFromAsyncCallback(T result) {
// general stuff (T is a subclass of Object)
doStuff(result);
}
}
然后你希望你的特定回调是这样的:
class SpecificCallback extends CallbackBase<Integer> {
public void doStuff(Integer result) {
// no need to cast
// do stuff with result
}
}
然后,您接受DoSomething
的{{1}}方法会接受AsyncCallback<Integer>
。
(迂腐旁注:请用Java中的小写字母开始所有方法)
修改强>
对于它的价值,我建议改变你的设计,使用构图而不是继承。在这种情况下,不是使用抽象类SpecificCallback
并扩展它,而是使用CallbackBase
的具体实现,可能看起来像这样:
AsyncCallback<T>