Forcing SingleTask implementors to also implement all the methods of List isn't very elegant, and default methods aren't meant to be used to define trait-like entities, which your SingleTask interface looks like.
There are several reasons why default methods-as-traits is a bad idea, the most obvious one being that any implementor can simply override your default method, ruining your trait.
And this is exactly what is happening here: since AbstractList explicitly declares get() and size() as abstract, it means SingleTask will inherit them, rather than the default implementations you may have had in a superinterface.
A class C inherits from its direct superclass and direct superinterfaces all abstract and default (§9.4) methods m for which all of the following are true:
No concrete method inherited by C from its direct superclass has a signature that is a subsignature of the signature of m....
- No concrete method inherited by C from its direct superclass has a signature that is a subsignature of the signature of m.
Bearing all that in mind the simplest solution is probably this:
public abstract class SingleTask extends AbstractList<Runnable> implements Runnable { @Override public final Runnable get(final int x) { if (x != 0) { throw new IndexOutOfBoundsException(); } return this; } @Override public final int size() { return 1; } @Override public abstract void run(); } An added bonusIts drawback is that it doesn't force implementorsyour tasks must extend SingleTask and thus can't extend anything else, on the plus side though they don't need to concern themselvesdeal with theirthe task also being a List, they only need to implement run() and that's all.
In the long run though, I would prefer composition over inheritance, and tasks simply returning a list of runnables rather than themselves being one.