tags:

views:

115

answers:

3

I have interface:

public interface CartService extends RemoteService{
    <T extends ActionResponse> T execute(Action<T> action);
}

I wish override 'execute' method in implementation:

public class XX implements CartService {

  @Override
  public <GetCartResponse> GetCartResponse execute(GetCart action) {
    // TODO Auto-generated method stub
    return null;
  }
}

But receive compiler error: The method execute(GetCart) of type XX must override or implement a supertype method

GetCart & GetCartResponse:

public class GetCart implements Action<GetCartResponse>{

}


public class GetCartResponse implements ActionResponse {
    private final ArrayList<CartItemRow> items;

    public GetCartResponse(ArrayList<CartItemRow> items) {
        this.items = items;
    }

    public ArrayList<CartItemRow> getItems() {
        return items;
    }

}

How can I override this method ?

+1  A: 

Use

public <GetCartResponse extends ActionResponse>
    GetCartResponse execute(GetCart action) {
    //do stuff
}

as the signature for the execute method in CartService, it should work.

I ahve tested that the follwing compiles; just substituted ActionResponse with Integer, and Action with List, for convenience.

CartService:

public interface CartService {
    <T extends Integer> T execute(List<T> action);
}

XX:

public class XX implements CartService {
    public <T extends Integer> T execute(List<T> action) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
bguiz
+1  A: 

The problem is the definition of the interface vs what the erausre should look like for your impl. In your example you have:

<T extends ActionResponse> T execute(Action<T> action);
public <GetCartResponse> GetCartResponse execute(GetCart action);

but according to the interface definition the implementation method should read:

public GetCartResponse execute(Action<GetCartResponse> action);

So I think you either need to change the signature of your interface or add another type parameter such as:

public interface CartService extends RemoteService{
    <T extends ActionResponse, U extends Action> T execute(U action);
}

or possibly something along the lines of:

public interface CartService extends RemoteService{
    <T extends ActionItem> ActionResponse<T> execute(Action<T> action);
}
M. Jessup
How did you coloured the text red in your first code snippet?
Martijn Courteaux
That's something the auto-syntax highlighter is doing automatically, not sure how or why.
M. Jessup
A: 

Your interface specifies that implementing classes must define that method for all T extends ActionResponse. You want to define them for specific actions, and responses - I think your interface needs to be

    public interface CartService<T extends ActionResponse, A extends Action<T>>
     extends RemoteService {
      public T execute(A action)
    }

and then implementation would be

public class XX implements CartService<GetCartResponse,GetCart> {
 //...
}

As written, you may not need to explicitly parametrize with an extension of Action type - as long as you can deal with any kind of Action that is parametrized by GetCartResponse and don't rely on specifics of the GetCart action. In which case, your interface should look something like:

public interface CartService<T extends ActionResponse> extends RemoteService {
 public T execute(Action<T> action);
}

and implementation

public class XX implements CartService<GetCartResponse> {
 public GetCartResponse execute(Action<GetCartResponse> action) {
  //...
 }
}
Carl