Snowy Coder Girl
Snowy Coder Girl

Reputation: 5518

Java Inheritance and Generics

I have some classes that look like this:

MODEL

public abstract class BaseEntity<O extends Object> { ... }

public class Person extends BaseEntity<Person> { ... }

COMMAND

public abstract class BaseCommand<BE extends BaseEntity<BE>> { ... }

public class PersonCommand extends BaseCommand<Person> { ... }

SERVICE

public interface BaseService<BE extends BaseEntity<BE>> {
    public BE create(BaseCommand<BE> command);
}

public interface PersonService extends BaseService<Person> { ... }

SERVICE IMPL

public abstract class BaseServiceImpl<BE extends BaseEntity<BE>> implements BaseService<BE> { }

public class PersonServiceImpl extends BaseServiceImpl<Person> implements PersonService {
    public Person create(PersonCommand personCommand) { ... }
}

The PersonServiceImpl class won't compile. It's not recognizing that the create() method is implementing the create() method from the BaseService interface. Can anyone tell why PersonCommand isn't being recognized as a BaseCommand<BE> (in the parameter list)?

Upvotes: 3

Views: 199

Answers (1)

C. K. Young
C. K. Young

Reputation: 222973

When overriding, method parameters are not covariant (that is, subclasses have to accept a type that the superclass also accepts, not anything narrower).

This is because people can use your PersonServiceImpl via the PersonService interface, which will accept an argument of type BaseCommand<Person> that is not necessarily a PersonCommand (imagine if you created a second class that extended BaseCommand<Person>).

If you make your method take a parameter of type BaseCommand<Person>, your code should compile correctly.

Upvotes: 7

Related Questions