In my project I have multiple strictly ordered types and I need them all to support a range operation - given two boundary values, return the list of all intermediary values.
To not repeat myself, I though I would create a "trait" like the following, which would declare the corresponding primitive operations and build a range method on top.
public interface Navigable {
public Navigable previous() throws UnsupportedOperationException;
public boolean isFirst();
public Navigable next() throws UnsupportedOperationException;
public boolean isLast();
public boolean precedes(Navigable other);
public default List<Navigable> range(Navigable to) {
Navigable from = this;
boolean invert = to.precedes(from);
if (invert) {
Navigable tmp = from;
from = to;
to = tmp;
}
List<Navigable> result = new LinkedList<>();
while (from.precedes(to)) {
result.add(from);
from = from.next();
}
result.add(to);
if (invert) {
reverse(result);
}
return result;
}
}
However, with such an interface, I need to implement the operations like this:
public class Item implements Navigable {
...
@Override
public boolean precedes(Navigable other) {
...
}
...
}
Which is, of course, incorrect. What I need is the following.
public class Item implements Navigable {
...
@Override
public boolean precedes(Item other) {
...
}
...
}
Hopefully what I'm trying to achieve is clear. What is the correct way to do this?
You have to make your interface generic and change a bit the abstract methods.
For example:
public interface Navigable<T extends Navigable> {
...
public boolean preceeds(T other);
..
}
Then, when you implement the interface, you will be able to do (without any compilation errors):
public class Item implements Navigable<Item> {
...
@Override
public boolean preceeds(Item other) {
...
}
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With