I have an Interface Worker like below:
public interface Worker<T> {
public void doAllTasks (List<? extends T> tasks);
}
There is an Abstract Class that uses above interface,
public abstract class AbstractWorker<T> implements Worker<T> {
...
public abstract void doAllTasks (List<? extends T> tasks);
...
}
And there is a concrete Worker extending from this Abstract class,
public class ConcreteWorker<T extends Task> extends AbstractWorker<T> {
@Override
public void doAllTasks(List<? extends T> tasks) {
....
}
}
Notice the Task in the above class definition? That is an interface. SpecialTask is a concrete class that implements Task interface. Now once this structure is there, I wish to use this classes in my main Application like below:
Class Application {
public AbstractWorker<? extends Task> myWorker;
main() {
....
List<SpecialTask> listOfTasks = new ArrayList<SpecialTask>();
myWorker = new ConcreteWorker<SpecialTask>();
myWorker.doAllTasks (listOfTasks); <-------------- ERROR!!!
}
}
IDE shows me the following error in the above marked line:
The method doAllTasks(List<? extends capture#3-of extends Task>) in the type
AbstractWorker<capture#3-of extends Task> is not applicable for the
arguments (List<SpecialTask>)
What I am trying to do is - in my main Application I want to first declare the Abstract version of my Worker first and later, based on some logic I want to instantiate a concrete version of that worker. I do not know before hand which particular implementation of Task I will need (so it could be the SpecialTask or AnotherSpecialTask etc. - assuming both of them implements Task)
Honestly being new to Java, I could not make any head or tail of that error message. Can someone please show me where am I going wrong?

The problem is that the type of myWorker is just AbstractWorker<? extends Task> - in other words, it doesn't know that the type argument is really SpecialTask. It could be an AbstractWorker<SomeOtherTask>, which wouldn't know what to do with a List<SpecialTask>.
If you only ever want myWorker to hold a worker that can deal with SpecialTask, you can just use:
public AbstractWorker<SpecialTask> myWorker;
That's still not depending on ConcreteWorker, but it is saying that it's definitely not just an AbstractWorker<SomeOtherTask> for example.
See more on this question at Stackoverflow