I’m writing an API on Android that will be used by an existing application, which I’m going to call the client. There is a lot of client code and I don’t really want to modify it. Right now the API implements a callback method as an interface. In order to save my self from writing lots of boiler plate code I decided to use generics and extensible classes. This design decision is making my API’s Callback interface use generics. In turn this is causing the complier to flag the client as needing to to specify type parameters where the callback is implemented. I don’t want to cause the client to have to use type parameters. In effect I want to shield the client code from having to specify types and hopefully prevent the client from specifying the wrong type.
Here is an example:
Example of an extensible API class to encapsulate basic functionality:
public abstract class BaseAPI<T> {
Callback mCallBack;
public BaseAPI(Callback<T> callback) {
mCallBack = callback;
}
public void doSomething() {
T response = getResponse();
if (mCallBack != null) {
mCallBack.onCallback(response)
}
}
public abstract T getResponse();
public interface Callback<T> {
public void onCallback(T response);
}
}
Example class that extends BaseAPI:
public class ExampleAPI extends BaseAPI<String> {
public ExampleAPI(Callback<String> callback) {
super(callback):
}
public String getResponse() {
String response = "blah";
return response;
}
}
Example client code (This is how I want it to look):
public class ClientView extends Activity implements Callback {
TextView mTextView;
onCreate() {
//pretend normal setup code is here
new ExampleAPI(this).doSomething();
}
onCallback(String response) {
mTextView.setText(response);
}
}
Example client code (This is the complier wants it to look):
public class ClientView extends Activity implements Callback<String> {
TextView mTextView;
onCreate() {
//pretend normal setup code is here
new ExampleAPI(this).doSomething();
}
onCallback(String response) {
mTextView.setText(response);
}
}
Any ideas? Does this make sense?
It seems to me like you have competing objectives, and that the solution is to simply move the mess somewhere else.
What about implementing an intermediate type hiding interface, like StringCallback:
Or more abusively, you can just mask it with an Object:
Then ClientView would implement one of these interfaces instead, at the end of the day your base API stuff should be happy, and your client code doesn’t have to carry the generics.
I’m not entirely sure why you want to do this, your client code should just specify the types.