I've added the code for an abstract thread class and 2 sub-classes. The structure and job of the threads (sub-classes) is identical except one difference: ONE of the sub-classes, RefreshData does not need the client parameter. I've overloaded the constructor in the sub-class but I'm not sure if the abstraction makes sense anymore. Moreover, can I do something to ensure that RefreshData doesn't use the inherited client parameter accidentally and ends up getting an NPE.     public abstract class BackgroundTask implements Runnable {      protected final Manager manager;      protected final Client client;      private long msSyncInterval;      private boolean shutdown; // has a setter     public BackgroundTask(final Manager manager, final long msSyncInterval) {        this.manager = manager;        this.client = null;        this.msSyncInterval = msSyncInterval;        this.shutdown = shutdown;    }    public BackgroundTask(final Manager manager, final Client client, final long msSyncInterval) {        this.manager = manager;        this.client = client;        this.msSyncInterval = msSyncInterval;        this.shutdown = shutdown;    }    @Override    public void run() {        while (!shutdown) {            executeTask();            // sleep for msSyncInterval        }    }    abstract void executeTask();}public class ExchangeData extends BackgroundTask {    public ExchangeData(final Manager manager, final Client client, final long msSyncInterval) {        super(manager, client, msSyncInterval);    }    @Override    void executeTask() {        // Some work here    }}public class RefreshData extends BackgroundTask {    public RefreshThrottleLimits(final Manager manager, final long msSyncInterval) {        super(throttleManager, msSyncInterval);    }    @Override    void executeTask() {        // Doesn't use the client    }}
Should I create an abstract runnable? I've 4 sub-classes which perform similar work but only 3 of them have identical constructors
java;object oriented;classes;inheritance
It would be better to implement the convenience constructors in terms of the other, more detailed one, like this:public BackgroundTask(final Manager manager, final long msSyncInterval) {    this(manager, null, msSyncInterval);}(Btw it seems you forgot the boolean shutdown parameter.)The manager and the client fields are not used in the posted code.If this is indeed what you have in your use case,then I think these fields don't belong in the parent class.Adding fields in the parent that itself doesn't need makes the code more complex:if you hadn't added those fields, you wouldn't be asking now what to do with one unused field.If the code you posted is not complete, and in fact the parent is really using those fields, then another option can be to use a dummy implementation of a client instead of a null value.Finally, have you considered using composition instead of inheritance?This is actually the single most important question to evaluate every time before choosing to use inheritance.You could rename BackgroundTask to BackgroundTaskRunner,and create a BackgroundTask interface with an executeTask method.Of course, sometimes inheritance is the answer.In this case I question your decision because of signs that seem to suggest otherwise:Inheritance is designed for is a relationships. Can you say that ExchangeData is a BackgroundTask? Maybe it's easier to from another angle: if you had to pick the one defining characteristic of ExchangeData, will it be that it's a BackgroundTask? Or will it be something else? It seems to me its main purpose is not really being a background task. It's main purpose is something else, and you just want to make it do its job in the background.Inheritance is the complex idea that one class is a specialization of another class (Code Complete) Here, this doesn't seem to be the case. Although you want to run ExchangeData in the background, it's certainly not a special case of BackgroundTaskThe idea of running stuff in the background is so common that there exist high-level utility classes for that in the JDK. Instead of using the low-level Runnable, you can probably benefit from using one of the high-level solutions, such as ExecutorService.All things considered, you know your problem domain the best,so you are in the best position to decide whether composition or inheritance is the right design. But at the minimum, you should at least consider this alternative.