Search code examples
javafieldsubclasssuperclass

In Java, can I somehow move field to superclass if subclasses have different types for them?


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;
}

Solution

  • 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:

    1. Cast customers (since it knows that customers is actually a PriorityQueue<Customer>, not just a Queue<Customer>), or

    2. 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.