Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limitation extending generics in java, any way to get around it?

I have the following model to make controllers in my application. Obviously, the full model is more complex but I will focus on the only part that is causing me problems:

public abstract AbstractController<T> {
    abstract protected Class<T> getType();
}

public ParentController extends AbstractController<Parent> {
    @Override
    protected Class<Parent> getType() {
        return Parent.class;
    }
}

Now I would like to extend the Parent object and have a controller for the son, it would look like this:

public SonController extends ParentController {
    @Override
    protected Class<Son> getType() {
        return Son.class;
    }
}

The problem is that the method getType() shows incompatibility in compilation (expects the class Parent).

I tried to play around with the generics but I can't find a solution. The method getType is used in several methods from the abstract controller and I would really like to avoid overriding those.

Any ideas would be wellcome.

like image 878
Gonzalo Calvo Avatar asked Aug 29 '18 13:08

Gonzalo Calvo


People also ask

Can a generic class be extended?

We can add generic type parameters to class methods, static methods, and interfaces. Generic classes can be extended to create subclasses of them, which are also generic.

Can generics be used with inheritance in several ways what are they?

Generics also provide type safety (ensuring that an operation is being performed on the right type of data before executing that operation). Hierarchical classifications are allowed by Inheritance. Superclass is a class that is inherited. The subclass is a class that does inherit.

Can I use polymorphism in generics?

The polymorphism applies only to the 'base' type (type of the collection class) and NOT to the generics type.


1 Answers

You could change the getType return Class<? extends T>.

abstract protected Class<? extends T> getType();

Then ParentController and SonController would look like

public class ParentController extends AbstractController<Parent> {
    @Override
    protected Class<? extends Parent> getType() {
        return Parent.class;
    }
}

public class SonController extends ParentController {
    @Override
    protected Class<? extends Parent> getType() {
        return Son.class;
    }
}
like image 105
user7 Avatar answered Oct 25 '22 09:10

user7