I'm working with Google Web Toolkit, and I'm having problems implementing a generic interface. I'm not really familiar with generics, doing an upgrade on someone else's code here.
Here's what I want to do: I want to have an implementation of a generic callback interface that does some logging, and then subclass that implementation in order to handle specific callback scenarios.
The interface is something like this:
public interface AsyncCallback<T> {
void MethodFromAsyncCallback(T result);
}
The abstract and concrete implementations look something like this:
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
}
}
The callbacks are required to be fired from
public interface MyServiceAsync {
public void DoSomeThing(AsyncCallback<Integer>);
}
And then it all comes together in a call that looks like this:
MyServiceAsync myService = (MyServiceAsync)GWT.create(MyServiceAsync.class);
myService.DoSomeThing(new SpecificCallback());
And here's where we have a problem!
When the GWT.create()
implements the interface I created, it demands that the type given to AsyncCallback
is specified (matches a type elsewhere, outside the scope of this question), hence making DoSomething(AsyncCallback<Integer>)
an Integer rather than an Object. This is beyond my control.
It complains that DoSomething()
takes AsyncCallback<Integer>
. I'm giving it something that inherits from something that is an AsyncCallback<Object>
. I guess with generics, concepts of inheritance get somewhat broken?
So my question is this:
Either how can I mush this together so that DoSomething()
will recognize that that SpecificCallback
meets it's requirements,
or how can I structure the relationship between CallbackBase
and SpecificCallback
so that duplicate code is avoided, but SpecificCallback
implements AsyncCallback<Integer>
directly?
Thanks.
What I think you need to do is define CallbackBase
like this:
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);
}
}
Then you want your specific callbacks to be like this:
class SpecificCallback extends CallbackBase<Integer> {
public void doStuff(Integer result) {
// no need to cast
// do stuff with result
}
}
Then your DoSomething
method, which accepts an AsyncCallback<Integer>
, will accept a SpecificCallback
.
(Pedantic sidenote: please start all methods with lowercase letters in Java)
Edit
For what it's worth, I'd suggest changing your design to use composition rather than inheritance. In this case, rather than using an abstract class CallbackBase
and extending it, you'd use a concrete implementation of AsyncCallback<T>
that might look something like this:
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With