Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A generic trait in Java

Tags:

java

generics

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?

like image 253
Dušan Rychnovský Avatar asked May 07 '26 19:05

Dušan Rychnovský


1 Answers

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) {
        ...
    }
    ...
}
like image 129
Konstantin Yovkov Avatar answered May 09 '26 08:05

Konstantin Yovkov