Reputation: 5518
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
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