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?