Java Inheritance and Generics - java

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)?

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.

Related

How to make method generic when using inheritance in Java?

I have class Employee and 3 classes that extends Employee class.
I also have EmployeeService interface where i want to have only one save method to handle saving each type of Employee. So i assumed that it could be solved using generics.
This is what i tried in EmployeeService interface:
public interface EmployeeService {
<SubRequestT extends Employee>EmployeeResponse save(SubRequestT requestT);
}
And class that provide implementation:
#Service
public class EmployeeServiceImpl implements EmployeeService {
// So here in argument i want to have to put any kind of Employee, for example:
#Override
public EmployeeResponse save(OfficeEmployee requestT) {
// Logic for saving employee
return null;
}
}
But when i changed from Employee type to any other, for example OfficeEmployee who is extending from Employee, complier is giving me an error. What is best way to solve this?
With "method generics" I (me & compiler) also struggle, but with "type generics" we can do that!
Assuming:
class Foo {/*...*/}
class Bar extends Foo {}
class Baz extends Foo {}
// extending your question to two generic parameters:
class FooResult {}
class BarResult extends FooResult {}
class BazResult extends FooResult {}
When we define our interface like:
interface FooI<I extends Foo, R extends FooResult> { //or with even more (fixed size) "generic parameters"
R save(I request);
}
We can override it like:
class BarImpl implements FooI<Bar, BarResult> {
#Override
public BarResult save(Bar bar) {
// ...
return ...;
}
}
class BazImpl implements FooI<Baz, BazResult> {
#Override
public BazResult save(Baz baz) {
// ...
return ...;
}
}

Java define Generic Class param with a const or static method

I'd like to improve my code especially my way to use Generic classes.
In my project I have about 30 classes like folowing :
GenericEntity<T extends Serializable>{
protected T id;
public T getId(){ return id;};
...
}
public class A extends GenericEntity<Integer>{
...
}
public interface IService<T extends GenericEntity, T extends Serializable>{
...
}
public class AService extends IService<A,Integer>{
...
}
I would like to specify the class of my entity Id only one time instead of one in GenericEntity and one in Service like that.
public class A extends GenericEntity<getIdType()>{
public final static Class getIdType(){
return Integer.class;
}
}
public class AService extends IService<A,A.getIdType()>{
...
}
I'm aware it doesn't work like that but I'm hoping there is a way to do it.
Thanks for your help.
Instead of:
class GenericEntity<T extends Serializable>{
protected T id;
public T getId(){ return id;};
}
// THESE ARE UNNECESSARY as far as I can tell
class A extends GenericEntity<Integer>{ }
class B extends GenericEntity<Long>{ }
// where U matches the generic type of GenericEntity<?>
interface IService<T extends GenericEntity<?>, U extends Serializable>{ }
class AService extends IService<A, Integer>{ }
class BService extends IService<B, Long>{ }
You could do this:
class GenericEntity<T extends Serializable> {
protected T id;
public T getIdFromEntity() { return id; }
}
// 'IService' can/should only know of 'id' as some type that extends 'Serializeable'
// So if something implements 'IService' then everything knows it will have
// a method with the signature 'T getGenericEntity(Serializable id);'
interface IService<T extends GenericEntity<?>> {
public T getGenericEntity(Serializable id);
}
// 'AService' knows that 'id' will be an 'Integer'
class AService implements IService<GenericEntity<Integer>> {
Map<Serializable, GenericEntity<Integer>> entityMap = new HashMap<>();
void someMethod() {
GenericEntity<Integer> entity = this.getGenericEntity(Integer.valueOf(1));
Integer i1 = entity.getIdFromEntity();
// ... do stuff
}
// even though 'AService' knows that 'id' will be an 'Integer'
// the 'IService' interface defines this as taking a 'Serializable'
// so it must keep that method signature.
#Override public GenericEntity<Integer> getGenericEntity(Serializable id) {
return entityMap.get(id);
}
}
class BService implements IService<GenericEntity<Long>> {
#Override public GenericEntity<Long> getGenericEntity(Serializable id) { return null; }
// ... similar to AService ...
}
This would cut out all your excess class X extends GenericEntity<SOME_TYPE> classes.
You would only need the one generic GenericEntity<T extends Serializable> and the one interface IService<T extends GenericEntity<?>>. Also, since they aren't generic AService and BService know the actual type that extends Serializeable (Integer and Long), so they don't need the extra info passed to them in generics.
Since IService is generic for any T extends GenericEntity<?> it shouldn't know a concrete type for genericEntity.getId() (and you probably shouldn't want it to). Also you should avoid making it concrete because it's an Interface.
The type of id as far as IService cares is Serializable, since IService<GenericEntity<?>> implies that the wildcard ? extends Serializeable since class GenericEntity<T extends Serializeable> requires it to.

Extending a generic implementer class

I have a DAO object that I'd normally extend with the entity class name like so:
public class DAO<T> {
private final Class<T> clazz;
public DAO(Class<T> clazz {
this.clazz = clazz;
}
}
public class EntityDAO extends DAO<Entity> {
public EntityDAO() {
super(Entity.class);
}
}
However, I have some abstract entities that I would like to create an abstract DAO that gets implemented into a concrete class later on:
public class DAO<T> {
private final Class<T> clazz;
public DAO(Class<T> clazz {
this.clazz = clazz;
}
}
public abstract class AbstractEntityDAO extends DAO<T extends AbstractEntity> {
public AbstractEntityDAO () {
super(AbstractEntity.class);
}
}
public abstract class EntityDAO extends AbstractEntityDAO <Entity> {
public EntityDAO() {
super(Entity.class);
}
}
But this doesn't work as the AbstractEntityDAO complains about an unexpected bound and it cannot resolve T. Is it possible to do this? And if so, how is it written?
This is using Java 1.7
Put the generic type definition on AbstractEntityDAO:
public abstract class AbstractEntityDAO<T extends AbstractEntity> extends DAO<T> {
...
}
With your current code AbstractEntityDAO <Entity> should make the compiler complain about AbstractEntityDAO not having generic paremeters.
Besides that your AbstractEntityDAO() constructor needs to accept a Class parameter as well. However, you don't need to pass the class as a parameter at all if you always use instances of classes with concrete types. Using reflection a class can determine the type of T if there is a concrete definition as in EntityDAO. The built-in reflection utilities provide no easy way to do this but fortunately you only need a little additional code to provide one, have a look here: http://www.artima.com/weblogs/viewpost.jsp?thread=208860
That's basically what we're doing as well. Here's a rough rundown of our approach:
abstract class BaseDAO<T> {
Class<?> entityClass;
BaseDAO() {
//this is based on the link I posted above but basically uses the actual concrete class
//(subclass determined by getClass() ) to extract the generic types and
//since we only have one we get the first one from the returned list
entityClass = ReflectionHelper.getTypes(getClass(), BaseDAO.class).get(0);
}
public T getEntity(Object id) {
...
}
}
abstract class TranslatableDAO<T extends TranslatableEntity> extends BaseDAO<T> {
...
}
//Users are not translatable
class UserDAO extends BaseDAO<User> {
...
}
//Products are translatable, i.e. Product extends TranslatableEntity
class ProductDAO extends TranslatableDAO<Product> {
...
}

Generic type parameter which implements generic interace

In a Java application, I'd like to use a generic type parameter which implements an interface which uses a generic parameter itself.
public interface SuperInterface<T> { ... }
public interface MyInterface extends SuperInterface<MyClass> { ... }
public class Worker<T extends SuperInterface<U>> extends SuperWorker<String, Boolean> {
}
However, the class declaration won't work like that. T should be of type MyInterface (or any other interface which implements the SuperInterface) and U should be of type MyClass (or any other class according to the interface).
You have to declare all of the type parameters at the top level. It's annoying, but that's how it is.
public class Worker<U extends MyClass, T extends SuperInterface<U>> { ...
The order of the parameters doesn't matter; you can also do Worker<T extends..., U extends...>. All that matters is that each is declared at the top level of the nested generics.
Here's a complete class:
public class MyClass {
public interface SuperInterface<T>{}
public interface MyInterface extends SuperInterface<MyClass> {}
public class Worker<U extends MyClass, T extends SuperInterface<U>> {}
public void compileTest() {
// just to make sure the declaration compiles
Worker<MyClass, MyInterface> worker = null;
}
}

Java child class not able to implement parent class's abstract method

I have the following. If I keep the #Override, I get an error that the method must implement or override a supertype method. If I remove it, I get an error that the child class must implement the inherited abstract method. Why won't the below code work, and how can I make it do what I intend?
BaseClass.java:
public abstract class BaseClass
{
...
protected abstract <T extends Inputs> T doStuff(T inputs);
public abstract static class Inputs
{
...
}
}
ChildClass.java:
public class ChildClass extends BaseClass
{
...
#Override
protected Inputs doStuff(Inputs inputs)
{
return inputs;
}
public static class Inputs extends BaseClass.Inputs
{
...
}
}
Try and:
public abstract class BaseClass<T extends BaseClass.Inputs>
and:
public class ChildClass extends BaseClass<ChildClass.Inputs>
Which means you need to change doStuff() so that it returns T (in BaseClass), without having a declared type variable:
public abstract T doStuff(T inputs);

Categories