Skip to main content
added 61 characters in body
Source Link
biziclop
  • 50k
  • 12
  • 80
  • 108

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.

JLS 8.4.8:

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.

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.

JLS 8.4.8:

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. 

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 bonus is that it doesn't force implementors to concern themselves with their 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.

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.

JLS 8.4.8:

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.

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(); } 

Its drawback is that your tasks must extend SingleTask and thus can't extend anything else, on the plus side though they don't need to deal with the task also being a List, they only need to implement run().

In the long run though, I would prefer composition over inheritance, and tasks simply returning a list of runnables rather than themselves being one.

added 547 characters in body
Source Link
biziclop
  • 50k
  • 12
  • 80
  • 108

Forcing SingleTask implementors to also extendimplement all the methods of AbstractListList 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.

JLS 8.4.8:

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. 

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 bonus is that it doesn't force implementors to concern themselves with their task also being a SingleTaskList implementors, they only need to implement every single method of Listrun() (which should be none of their concern)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.

Forcing SingleTask implementors to also extend AbstractList 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.

JLS 8.4.8:

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. 

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 bonus is that it doesn't force SingleTask implementors to implement every single method of List (which should be none of their concern).

In the long run though, I would prefer composition over inheritance, and tasks simply returning a list of runnables rather than themselves being one.

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.

JLS 8.4.8:

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. 

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 bonus is that it doesn't force implementors to concern themselves with their 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.

added 547 characters in body
Source Link
biziclop
  • 50k
  • 12
  • 80
  • 108

Forcing SingleTask implementors to also extend AbstractList 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.

JLS 8.4.8:

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. 

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(); } 

*There are several reasons why default methods-as-traitsAn added bonus is a bad idea, the most obvious one being that any implementor can simply override your defaultit doesn't force SingleTask implementors to implement every single method of List (which should be none of their concern).

In the long run though, ruining your traitI would prefer composition over inheritance, and tasks simply returning a list of runnables rather than themselves being one.

Forcing SingleTask implementors to also extend AbstractList isn't very elegant, and default methods aren't meant to be used to define trait-like entities, which your SingleTask interface looks like.*

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(); } 

*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.

Forcing SingleTask implementors to also extend AbstractList 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.

JLS 8.4.8:

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. 

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 bonus is that it doesn't force SingleTask implementors to implement every single method of List (which should be none of their concern).

In the long run though, I would prefer composition over inheritance, and tasks simply returning a list of runnables rather than themselves being one.

Source Link
biziclop
  • 50k
  • 12
  • 80
  • 108
Loading