Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics, why is it illegal to use inheritance in generics?

Tags:

java

generics

I have this structure:

///Creep.java///
public interface Creep extends Movable<Position2D> {
  ...
}


///Movable.java///
public interface Movable<T extends Position2D> {
        ...
    void setMovementStrategy(MovementStrategy<Movable<T>> movementStrategy);
    MovementStrategy<Movable<T>> getMovementStrategy();
}


///MovementStrategy.java///
public interface MovementStrategy<T extends Movable<? extends Position2D>> {
  void executeMovement(T movable);
}


///CreepImpl.java///
public class CreepImpl implements Creep {
...

 @Override
 public void setMovementStrategy(MovementStrategy<Creep> movementStrategy) {
    // TODO Auto-generated method stub

 }

 @Override
 public MovementStrategy<Creep> getMovementStrategy() {
    return null;
 }

}

My problem is that generics doesn't like MovementStrategy<Creep> but it does accept MovementStrategy<Movable<Position2D>> Which i think is strange as Creep extends Movable<Position2D>. This in the context of the methods public MovementStrategy<Creep> getMovementStrategy() and public MovementStrategy<Creep> getMovementStrategy()

Isn't this possible? or maybe im doing something wrong?

Any help is appreciated!

EDIT

Forgot to include MovementStrategy source.. doh!

like image 738
netbrain Avatar asked Dec 10 '22 06:12

netbrain


1 Answers

Probably you don't even need generics with MovementStrategy. Try not to create that much generics complexity.


Original answer: You can use the extends keyword: MovementStrategy<? extends Movable>

This is needed to preserve compile-time safety.

Imagine the following was possible: Creep extends Movable, Wind extends Movable

MovementStrategy<Movable> strategy = new MovementStrategy<Wind>();
strategy.setTargetObject(new Creep()); //fails

The 2nd like fails at runtime, because it expects Wind, but you give it a Creep

like image 166
Bozho Avatar answered Dec 22 '22 01:12

Bozho