Should implement the default interface method?

Here is a simplified example showing my problem:

import java.util.List; public interface SingleTask extends List<Runnable>, Runnable { default Runnable get(final int x) { if (x != 0) { throw new IndexOutOfBoundsException(); } return this; } default int size() { return 1; } } import java.util.AbstractList; public class MyTask extends AbstractList<Runnable> implements SingleTask { @Override public void run() { System.out.println("hello"); } } 

In SingleTask I provide implementations for the get and size methods, which are the only abstract methods from AbstractList . However, when I compile MyTask , I still get errors like:

MyTask type must implement the inherited abstract method AbstractCollection.size ()

or

MyTask.javahaps: error: MyTask is not abstract and does not override the abstract get (int) method in AbstractList

(depending on the compiler). I of course use java 8.

I have two questions:

  • Why am I getting these errors? I expected him to find out about the default implementation.
  • If it should not work like that, then what is the easiest way to use these two methods in MyTask without copying all the code?
+5
source share
2 answers

Forced SingleTask constructors, which also implement all List methods, are not very elegant, and the default methods are not intended to define objects that are similar to the type your SingleTask interface looks like.

There are several reasons why default method methods are a bad idea, the most obvious of which is that any developer can simply override your default method, destroying your trait.

And this is exactly what is happening here: since AbstractList explicitly declares get() and size() as abstract , this means that SingleTask inherits them, and not the standard implementations that you might have had in the superinterface.

JLS 8.4.8 :

Class C inherits from its direct superclass and direct superinterfaces of all abstract and default (ยง 9.4) methods m, for which everything is true:

...

  • No particular method that C inherits from its direct superclass has a signature, which is a subset of signature m.

Given all this, 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 disadvantage is that your tasks must expand on SingleTask and therefore cannot distribute anything else on the plus side, although they do not need to deal with the fact that the task is also a List , they only need to implement run() .

In the long run, although I would prefer composition over inheritance, tasks simply return a list of runnables rather than themselves.

+6
source
  • Why am I getting these errors? I expected him to find out about the default implementation.

I think @biziclop correctly addressed this in his answer . In short, since AbstractList declares the get(int) and size() methods abstract, they take precedence over your default implementations in SingleTask .

  1. If this should not work like that, then what is the easiest way to use these two methods in MyTask without copying all the code?

The easiest way would be to override the get(int) and size() MyTask in MyTask so that they delegate your default methods in the SingleTask interface:

 public class MyTask extends AbstractList<Runnable> implements SingleTask { @Override public void run() { System.out.println("hello"); } @Override public Runnable get(int index) { return SingleTask.super.get(index); } @Override public int size() { return SingleTask.super.size(); } } 

With this approach, you would like to delegate your default methods to SingleTask . I don't think this is bad (at least you don't need to use an attribute). In addition, it makes sense to write these methods so that you can choose which interface provides the default implementation.

+2
source

Source: https://habr.com/ru/post/1244349/


All Articles