实现通用接口的类的子类

5

我在使用 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的类型(匹配在此问题范围之外的某个类型),因此使DoSomething(AsyncCallback<Integer>)成为一个整数而不是一个对象。这超出了我的控制。

它抱怨DoSomething()采用AsyncCallback<Integer>。我正在提供继承自AsyncCallback<Object>的东西。我想使用泛型,继承概念会有所破坏?

所以,我的问题是:

要么如何将它们结合起来,使DoSomething()能够识别SpecificCallback符合其要求,

要么如何构建CallbackBaseSpecificCallback之间的关系,以避免重复代码,但SpecificCallback直接实现AsyncCallback<Integer>

谢谢。

1个回答

10
我认为您需要这样定义CallbackBase:
```html

我认为您需要这样定义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方法,接受一个AsyncCallback<Integer>,将会接受一个SpecificCallback

(小题外话:请在Java中以小写字母开头开始所有方法)

编辑

值得一提的是,我建议您改变设计,使用组合而不是继承。在这种情况下,您不会使用抽象类CallbackBase并扩展它,而是使用AsyncCallback<T>的具体实现,可能看起来像这样:

class GeneralCallbackWrapper<T> implements AsyncCallback<T> {
  private final AsyncCallback<? super T> delegate;

  public GeneralCallbackWrapper(AsyncCallback<? super T> delegate) {
    this.delegate = delegate;
  }

  public void MethodFromAsyncCallback(T result) {
    // general stuff here
    delegate.MethodFromAsyncCallback(result);
  }
}

回复:编辑。是的,那很有道理。我一开始就想把它改成那样,但觉得还是一步一步解决我的困惑比较好。;) - Ipsquiggle
这两个能否扩展以考虑两种可能的类型?例如,在概念上等同于“实现AsyncCallback<Integer>,AsyncCallback<OtherType>”? - Ipsquiggle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接