AM01
AM01

Reputation: 314

Generics override confusion

I have the following class structure.

public abstract class X { }
public class Y extends X { }

And I want to do the following:

public abstract class Action {
  public abstract <T extends X> void execute(T t);
}

public class SomeAction extends Action {
  public void execute(Y y) { }
}

The compiler is giving me following error:

The Type SomeAction must implement the inherited abstract method Action.execute(T)

I do want to override execute(), but I want the parameter to be a subclass of X.

What am I doing wrong here?

Upvotes: 0

Views: 79

Answers (4)

JB Nizet
JB Nizet

Reputation: 692023

You're breaking the Liskov principle: the base Action's execute method is able to execute any kind of X. But in the subclass, you limit it to executing only Y instances. That's reducing the contract, instead of extending it.

Upvotes: 1

Louis Wasserman
Louis Wasserman

Reputation: 198321

It sounds like you want T extends X to be a property of the class extending Action, not the method invocation. You should write

 public abstract class Action<T extends X> {
   public abstract void execute(T t);
 }

and then

 public class SomeAction extends Action<Y> {
    ...
 }

Upvotes: 1

rgettman
rgettman

Reputation: 178303

Try making the class Action generic, instead of one of its methods.

public abstract class Action<T extends X>
{
   public abstract void execute(T t);
}

Then you can assign the generic type parameter T to be Y in SomeAction:

public class SomeAction extends Action<Y>
{
   public void execute(Y y) {}
}

Upvotes: 2

Juned Ahsan
Juned Ahsan

Reputation: 68715

  public <T extends X> void execute(T t);

is an abstract method as it does not have any body. it should be marked as abstract.

So in your child class you need to override this or mark both method and subclass as abstract.

Upvotes: 1

Related Questions