Brandon Sherman
Brandon Sherman

Reputation: 674

In Java, how do I make instance variables of a subclass have the type of the subclass, rather than of the superclass?

I'm writing a HuffmanTree class for a Java project that inherits from a BinaryNode class. I want to work with HuffmanTree nodes instead of BinaryNode nodes. BinaryNode has left and right instance variables of type BinaryNode, and I want HuffmanTree to have the same instance variables (i.e. left and right), but of type HuffmanTree instead.

How would I go about doing this? Thanks!

EDIT: Here's some of the BinaryNode code:

public class BinaryNode<T> implements BinaryNodeInterface<T>, 
                               java.io.Serializable
{
//The BinaryNode's instance variables were changed to protected so we can access them
//from the HuffmanTree class.
private T data;
private BinaryNode<T> left;
private BinaryNode<T> right;

public BinaryNode()
{
    this(null); // call next constructor
} // end default constructor

public BinaryNode(T dataPortion)
{
    this(dataPortion, null, null); // call next constructor
} // end constructor

public BinaryNode(T dataPortion, BinaryNode<T> leftChild,
                               BinaryNode<T> rightChild)
{
    data = dataPortion;
    left = leftChild;
    right = rightChild;
} // end constructor

Upvotes: 0

Views: 106

Answers (1)

Paul Hicks
Paul Hicks

Reputation: 13999

Guessing from the names of the classes and interfaces, the first step would be to change the declaration of left and right to

protected BinaryNodeInterface<T> left;
protected BinaryNodeInterface<T> right;

Then your BinaryNode constructor can be

public BinaryNode(T dataPortion, BinaryNode<T> leftChild,
                           BinaryNode<T> rightChild)
{
    data = dataPortion;
    left = leftChild;
    right = rightChild;
} // end constructor

and your HuffmanTree constructor can be

public HuffmanTree(T dataPortion, HuffmanTree<T> leftChild,
                           HuffmanTree<T> rightChild)
{
    data = dataPortion;
    left = leftChild;
    right = rightChild;
} // end constructor

And all should work. You can even change the BinaryNode constructor to

public BinaryNode(T dataPortion, BinaryNodeInterface<T> leftChild,
                           BinaryNodeInterface<T> rightChild)
{
    data = dataPortion;
    left = leftChild;
    right = rightChild;
} // end constructor

That would probably do the trick too, with no code duplication.

Note that once you do this, any existing code that assumes that left and right are instances of BinaryNode<T> will have to be updated. The best thing to do is to change the code to rely only on BinaryNodeInterface<T>, but that's not always possible.

Inside BinaryNode methods, it should be safe (depending on your methods' contract) to simply cast: BinaryNode<T> node = (BinaryNode<T>) left;. In HuffmanTree methods, it might not be safe to call HuffmanTree<T> node = (HuffmanTree<T>) left, since left might be a BinaryNode without being a HuffmanTree. You'll have to work out the logic in these cases yourself.

Upvotes: 1

Related Questions