In my Java program, I have two classes that are really similar, and it would make a lot of sense to create a superclass for them to subclass and generalize a bunch of their methods.
The only problem is that one of their key fields is implemented in one as a Queue
and in one as a PriorityQueue
.
Is there any way to superclass these and somehow generalize the field type and let the subclasses pick what it will perhaps on instantiation?
public Base{
}
public Sub1{
Queue<Customer> customers;
}
public Sub2{
PriorityQueue<Customer> customers;
}
Yes, since PriorityQueue
implements Queue
. If you want to delegate creation to subclasses, have them pass the appropriate Queue
to use to the base constructor:
public class Base {
protected final Queue<Customer> customers;
protected Base(Queue<Customer> c) {
this.customers = c;
}
}
public class Sub1 extends Base {
Sub1() {
super(new WhateverQueue<Customer>());
}
}
public class Sub2 extends Base {
Sub2() {
super(new PriorityQueue<Customer>());
}
}
I should mention that if Sub2
needs to use methods that are specific to PriorityQueue
(such as comparator
) in some Sub2
-specific method, it can either:
Cast customers
(since it knows that customers
is actually a PriorityQueue<Customer>
, not just a Queue<Customer>
), or
Declare its own instance field which will keep the typed reference:
private PriorityQueue<Customer> priorityCustomers;
Sub2() {
super(new PriorityQueue<Customer>());
this.priorityCustomers = (PriorityQueue<Customer>)(this.customers);
}
#2 keeps the casting required to a minimum and nicely contained to just the constructor, making it easier to change PriorityQueue<Customer>
to something else later.