2

I have those two interfaces:

public interface ApiResultCallback {
    void onSuccess(RestApi.Success<?> successResult);
    void onFailure(RestApi.Failure failureResult);
}

public interface GetHappyCowsCallback extends ApiResultCallback {
    void onSuccess(RestApi.Success<List<HappyCow>> successResult);
}

Where Success and Failure are:

public static class Success<T> extends ApiResult {
    public T data;
}

public static class Failure extends ApiResult {
    public String message;
}

I get an error in GetCleverPointsCallback interface saying that

both methods have same erasure but neither overrides the other.

What does that mean? Shouldn't the method from GetHappyCowsCallback override the method of its parent?

What I'm trying to achieve here is some kind of mapping between callbacks and their data without having to implement long mapping functions or even worse, duplicating the Success class like this:

public static abstract class Success<T> extends ApiResult {
    public T data;
}

public static class ListHappyCowSuccess extends Success<List<HappyCow>> {
}
TheCrafter
  • 1,909
  • 2
  • 23
  • 44
  • From [here](http://stackoverflow.com/questions/17116845/implementing-comparable-compareto-name-clash-have-the-same-erasure-yet-neith): "These methods have the same erasure, meaning that once the compiler strips out generic type information, there will no longer be a way to differentiate them at runtime." – Frecklefoot Apr 27 '16 at 13:58
  • @Frecklefoot Ok that makes sense but what about this part: "but neither overrides the other" ? Shouldn't the second method override the first? – TheCrafter Apr 27 '16 at 14:00
  • I'm not sure since Java isn't my specialty at the moment, but a [Google search](https://www.google.com/search?q=java+error+both+methods+have+same+erasure+but+neither+overrides+the+other.&ie=utf-8&oe=utf-8) for the error yielded dozens of good results. I hope that helps. – Frecklefoot Apr 27 '16 at 14:02

1 Answers1

3
void onSuccess(RestApi.Success<?> successResult);

And

void onSuccess(RestApi.Success<List<HappyCow>> successResult);

Do not have the same signature. So the second does not override the first


What you're trying to do can be achieved by making the interface generic:

public interface ApiResultCallback<T> {
    void onSuccess(RestApi.Success<T> successResult);
    void onFailure(RestApi.Failure failureResult);
}

public interface GetHappyCowsCallback extends ApiResultCallback<List<HappyCow>> {
}

In fact, you probably don't need the second interface at all. Such pseudo-typedefs are even considered an anti-pattern, because the new types cannot be exchanged with their equivalents.

If I have a method like this:

void myMethod(GetHappyCowsCallback callback);

I can not pass an ApiResultCallback<List<HappyCow>> to it.


In most cases interface overriding doesn't really make sense. Unless it involves default methods:

interface InterfaceA {
    public void doSomething();
}

interface InterfaceB extends InterfaceA {
    @Override
    public default void doSomething() {...} // Provides a default implementation
}
Jorn Vernee
  • 31,735
  • 4
  • 76
  • 93
  • Hmm yeah that works. To be honest I didn't even try to think so simple... I thought the answer was somewhere deep into generics documentation. Thanks! – TheCrafter Apr 27 '16 at 15:32