I'm implementing a special priority queue. The implementation protects the value of queued items from being changed while being queued. It's a priority queue optimized for a certain use case which needs that invariant. Doing that, I ran into a problem concerning java inheritance and type.
The implementation consists of an interface defining the queue and a class defining a queued item. The latter should be extended by a class for concrete objects to be put into the queue.
The queue interface:
public interface PriorityQueueInterface<T extends Queueable> {
    void add(T elem);
    boolean remove(T element);
    T poll();
}
The queueable item class:
public class Queueable {
    private PriorityQueueInterface<? extends Queueable> queue;
    private boolean queued = false;
    private double value;
    public Queueable(PriorityQueueInterface<Queueable> queue) { this.queue = queue; }
    public void setValue(double value) {
        if (queued) throw new RuntimeException("can't set value while queued");
        this.value = value;
    }
    public double getValue() { return value; }
    public boolean queue() {
        if (queued) return false;
        queue.add(this);
        queued = true;
        return true;
    }
    public boolean unqueue() {
        if(!queued) return false;
        queue.remove(this);
        queued = false;
        return true;
    }
}
Sample use of Queueable:
public class QueueableTestItem extends Queueable {
    public QueueableTestItem(PriorityQueueInterface<QueueableTestItem> queue) {
        super(queue);
    }
}
I'm obviously doing something wrong here, the error is:
The call queue.add(this) in Queueable.queue is invalid, as type ? extends Queueable is expected while Queueable is provided.
I want to define the controlled queueing and unqueueing into the Queueable class though - how do I set the types correctly to make this work?
If the reasons for choosing this way are not obvious from the example, it's because I simplified it for providing a minimal example. It's a cutout from a much bigger context.
UPDATE
This is why I think, that How can I add to List<? extends Number> data structures? doesn't answer my question:
I understand, that I cannot add to a collection of a generic type (as described in that post).
When extending Queueable to e.g. QueueableTestItem then QueueableTestItem.queue is supposed to hold only elements of type QueueableTestItem.
The class Queueable exists to define the mechanics of using the queue, but it's not meant to be used as is - it's meant to be extended.
So the question is: what's the correct java syntax for that concept?
