Why would you do this? I notice that in practice, the ServiceBase extension always uses the same class name as T is declared; so there really isn’t any magical polymorphic benefit here.
Generics do not exist to create magical polymorphism. This is mainly a way to add type constraints at compile time to reduce the awkward type and type of error at runtime.
In your case, suppose that the ServiceBase
class is abstract and has a process()
method, which should create a new instance of a concrete class with each call, which we declare in a parameterized type.
We call this abstract createService()
method.
Without using generics, we can declare such a method as public abstract ServiceBase createService()
.
ServiceBase without generics
public abstract class ServiceBase implements Service { public abstract ServiceBase createService(); @Override public void process() { createService().process(); } }
With this declaration, a concrete class can return any instance of ServiceBase.
For example, the next child class will compile because we are not forced to change the return type of createService()
to the current declared type.
MyService without generics
public class MyService extends ServiceBase { @Override public ServiceBase createService() { return new AnotherService(); } }
But if I use generics in the base class:
ServiceBase with generics
public abstract class ServiceBase<T extends Service> implements Service { public abstract T createService(); @Override public void process() { createService().process(); } }
A particular class has no choice; it is forced to change the return type of createService()
with the declared parameterized type.
MyService with generics
public class MyService extends ServiceBase<MyService> { @Override public MyService createService() { return new MyService(); } }