0

I have a class of a binary search tree:

    class BSTree<T> {
       ...

       protected void insert(BSNode<T> parent, int side, BSNode<T> child){
          ... // Binary tree insertion logic
       }

       public void add(T data){
          ...
          parent, side, child = search(data) // this line is pseudo code
          insert(parent, side, child) // instance insertion logic
       }

       ...
    }

My tree's nodes are instances of the BSNode class.

I am implementing an extending class of the BSTree - the AVLTree class, which is using an extension of the BSNode - AVLNode extends BSNode<Integer>

This is the AVLTree class:

class AVLTree extends BSTree<Integer>{
   ...

   /* overrides BSTree insert() with slightly different parameters, 
      which inherit from the parameters of the BSTree insert() method */
   protected void insert(AVLNode parent, int side, AVLNode child){
      ... // AVL tree insertion logic
   }

   ...
}

My question is:

I want the insert() method in AVLTree to override the insert() method in BSTree, so that when called from within add(), the correct method will be called based on the object's class.

How can I override the method insert from the BSTree class inside AVLTree to take AVLNodes as arguments?

Cœur
  • 37,241
  • 25
  • 195
  • 267
RazK
  • 45
  • 8

2 Answers2

1

You have to provide the implementation as type parameter (if the nodes are inner classes, you have to use AVLTree.AVLNode).

class AVLTree extends BSTree<Integer, AVLNode> {
    protected void insert(AVLNode parent, int side, AVLNode child) {
        ...
    }
    ...
}

and

class BSTree<T, T_NODE extends BSNode<T>> {
    protected void insert(T_NODE parent, int side, T_NODE child) {
        ...
    }
    ...
}
Nevay
  • 784
  • 5
  • 9
  • What is `Node`? – Jacob G. May 13 '17 at 18:29
  • 1
    Just a type variable like T, any name would be valid but in my opinion the code is more readable if it is something like 'Node'. – Nevay May 13 '17 at 18:29
  • 1
    Conventionally, it should only be a single, capital letter. Javadocs exist to explain what generic types mean :P – Jacob G. May 13 '17 at 18:30
  • 1
    I know, but in this case I would prefer a meaningful name over a single letter name such as N (to comply a bit more with conventions, one could use an all upercase name, i.e. T_NODE (names like T_PRED etc. are often used in java classes)). – Nevay May 13 '17 at 18:33
  • Thanks! That's a great idea, I was actually using a typed parameter for the node type before - but then encountered a problem `Type parameter 'K' cannot be instantiated directly` which is caused because of type erasure and all the workaround for this seemed too complicated for the task at hand. Maybe you have an idea for a simple workaround? – RazK May 13 '17 at 18:34
  • http://stackoverflow.com/a/2900933/7294647 - I've never seen `T_NODE` or anything like it used before. – Jacob G. May 13 '17 at 18:34
  • 1
    For example java.util.Spliterator.OfPrimitive uses T_CONS and T_SPLITR. – Nevay May 13 '17 at 18:35
  • 1
    @RazK Not sure if it will help as I don't know your exact implementation: You could provide an abstract T_NODE newNode(...) method in your BSTree class and override it accordingly in your AVLTree class. – Nevay May 13 '17 at 18:39
  • 2
    The convention for type parameter names is to use a single uppercase letter. Using a long name can confuse people who actually follow the industry-standard naming conventions because the long name looks like some other kind of name instead of a type parameter. It's best to set aside one's idiosyncratic justifications and do what works for the community at large. No one is an island. Ask not for whom the bell tolls; it tolls for thee. – Lew Bloch May 13 '17 at 20:50
  • 1
    I agree for the common usecases of letters like K, E, T, U, V, R (and would agree that N would be suitable here) - but to defend my idiosyncratic justifications a bit: blindly following this one letter convention can significantly reduce readability (applies mainly to classes with multiple type parameters, imagine something like `OfPrimitive` instead of `OfPrimitive` (part of `java.util.streams.Nodes`) - these longer names are mostly used by java.util.stream classes).. :) – Nevay May 13 '17 at 21:31
-1

You cannot override a method with another method having different signature. So, you cannot override protected void insert(BSNode<T> parent, int side, BSNode<T> child) with smth like protected void insert(AVLNode<T> parent, int side, BSNode<T> child).

Ivan Pronin
  • 1,768
  • 16
  • 14