Override method with broken generics (method not found)

I am trying an @Override method in a class that may look like a complex inheritance structure, but in fact it will be quite simple, however I cannot get it to work.

 public interface Action { } public interface Result { } public interface Player<A extends Action, R extends Result> { default public <P extends Player<A, R>> void onPostAction(final P target, final A action, final R result) { } } abstract public class GesturePlayer<A extends Action, R extends Result> implements Player<A, R> { } abstract public class RPSPlayer extends GesturePlayer<RPSGesture, RPSResult> { } public class RPSHumanPlayer extends RPSPlayer { @Override public void onPostAction(final RPSPlayer target, final RPSGesture gesture, final RPSResult result) { } } 

I get an error in @Override onPostAction , why can't it find the correct method to override?

This is for the implementation of Rock-Paper-Scissors for people interested in where this name comes from.

The exact error message is:

a method does not override or does not implement a method from a supertype

My goal is to still use the current class, so for RPSHumanPlayer I really want to have this signature:

 public void onPostAction(final RPSHumanPlayer target, final RPSGesture gesture, final RPSResult result) { } 
+6
source share
1 answer

The onPostAction method in Player itself is common. You have identified P there. Therefore, any method that overrides it should also be common.

Try

 public class RPSHumanPlayer extends RPSPlayer { @Override public <P extends Player<RPSGesture, RPSResult>> void onPostAction(final P target, final RPSGesture gesture, final RPSResult result) { } } 

A and R already defined by GesturePlayer as RPSGesture and RPSResult , but P still needs to be declared.

Adding

If it must be an exact signature, then you need to define P along with A and R in the Player interface:

 public interface Player<A extends Action, R extends Result, P extends Player<A, R, P>> { default public void onPostAction(final P target, final A action, final R result) { } } 

Then the GesturePlayer changes accordingly:

 abstract public class GesturePlayer<A extends Action, R extends Result, P extends Player<A, R, P>> implements Player<A, R, P> { } 

Then RPSPlayer defines itself as P

 abstract public class RPSPlayer extends GesturePlayer<RPSGesture, RPSResult, RPSPlayer> { } 

And RPSHumanPlayer can have the method as is:

 public class RPSHumanPlayer extends RPSPlayer { @Override public void onPostAction(final RPSPlayer target, final RPSGesture gesture, final RPSResult result) { } } 
+3
source

All Articles