Hello. I'm doing a lab assignment and I have several subclasses extending the base class. I'm not sure how to "override" the methods and implementations in the supers, because every time my driver class calls a method on my subclass, the superclass method gets called. Heck even within the subclass any calls to the method (its a recursive method) refer to the superclass version of it. Yes, based on prior research I do know java doesn't have anything like a virtual method.

I have some idea based on prior research that I need to leave my superclass methods as stubs. Which means I've wasted a ton of time writing and debugging those methods, because they are unnecessary. -.- I blame the instructor for his flakey UML diagaram in that case. The guy is kind of an airhead. xD

Recommended Answers

All 8 Replies

I have some idea based on prior research that I need to leave my superclass methods as stubs.

No, that's wrong. If you create a method in a subclass that has the same signature (name, return type, parameter types) as a method in the superclass then that's an override. The superclass method does not have to be "stub" or abstract - it can be (usually is) a full method definition.
If yours isn't working then either the signatures are different or there's something wrong with the way you are calling them.

Oracle's tutorial may clear up your confusion, but if not, post your code here for more help.

ps: A simple example: The Object class defines and implements a method String toString() that returns its class and hash as text for any object.
Every class extends Object (directly or indirectly) and most implement their own version of toString that returns something more relevant. Java automatically uses the correct version of toString whenever it is called eg when you print an object using println

My code then:

Note: AVLNode inherits from Node

public class AVLTree extends BinarySearchTreeWithRotate {

    public void add(AVLNode present, int addThis) {
        if (root != null) {
            if (present != null) {
                if (addThis < present.getData()) {
                    // Go left and decrement
                    if (present.getLeft() != null) {
                        System.out.println("Branched left");
                        add(present.getLeft(), addThis);
                    } else {
                        System.out.println("Added node left");
                        present.setLeft(new AVLNode(addThis));
                    }
                    present.decrement();
                } else if (addThis > present.getData()) {
                    // Go right and increment
                    if (present.getRight() != null) {
                        System.out.println("Branched right");
                        add(present.getRight(), addThis);

                    } else {
                        System.out.println("Added node right");
                        present.setRight(new AVLNode(addThis));
                    }
                    present.increment();
                } else {
                    System.out.println("ERROR. Value already exists!");
                    return;
                }
            }
        }
    }

    public AVLNode delete(AVLNode past, AVLNode present, int deleteThisData) {
        AVLNode tmp = null;
        if (root != null) // Root must contain something
        {
            if (present != null) // Present must be non-null
            {
                if (deleteThisData < present.getData()) // If less
                {
                    if (present.getLeft() != null) { // If left is not null
                        tmp = delete(present, present.getLeft(), deleteThisData); // Go
                                                                                    // left
                                                                                    // down
                                                                                    // the
                                                                                    // branch
                                                                                    // and
                                                                                    // store
                                                                                    // whichever
                                                                                    // matches
                                                                                    // the
                                                                                    // node
                                                                                    // data
                        present.decrement();
                    }
                } else if (deleteThisData > present.getData()) // If greater
                {
                    if (present.getRight() != null) {
                        tmp = delete(present, present.getRight(), deleteThisData);
                        present.increment();
                    }
                } else if (deleteThisData == present.getData()) {
                    if (past != null) {
                        if (past.getLeft().equals(present)) {
                            past.setLeft(tmp);
                        } else if (past.getLeft().equals(present)) {
                            past.setRight(tmp);
                        }
                    }
                }

                System.out.println("Present node balance=" + present.getBalance());
            }
            return tmp;
        }
    }
}

import java.util.Scanner;

public class Driver {

    static Scanner forInput = new Scanner(System.in);
    static AVLTree avlTree = new AVLTree();
    static char controlChar = 0;

    public static void main(String[] args) {
        while (true) {
            System.out.println(
                    "Enter P to print the tree, A to add a new Node, F to find a reference to a value, D to delete a node, or Q to quit:\t");
            if (forInput.hasNext()) {
                char[] inpt = forInput.next().toLowerCase().toCharArray();
                controlChar = inpt[0];
            }
            switch (controlChar) {
            case 'p':
                printTree();
                break;
            case 'a':
                addNode();
                break;
            case 'f':
                findNode();
                break;
            case 'd':
                deleteNode();
                break;
            case 'q':
                System.out.println("Good bye!");
                return;
            default:
                break;
            }
        }
    }

    public static void deleteNode() {
        while (true) {
            String tmp = getString("Enter the value of the node to delete from the tree:\t");
            if (tmp != null) {
                avlTree.delete(null, avlTree.getRoot(), Integer.parseInt(tmp));
                return;
            }
        }
    }

    public static void printTree() {

        while (true) {
            controlChar = getString("Enter P to print in Post order or Q to return to the main menu:\t")
                    .toCharArray()[0];
            switch (controlChar) {
            case 'p':
                avlTree.print(avlTree.getRoot());
                break;
            case 'q':
                return;
            default:
                break;
            }
        }
    }

    public static void findNode() {
        Node returnVal = null;
        String tmp;
        while (true) {
        tmp = getString("Enter a value to find:\t");
            if (tmp != null) {
                returnVal = avlTree.find(avlTree.getRoot(), Integer.parseInt(tmp));
                if (returnVal != null) {
                    System.out.println("Found value: " + returnVal);
                } else {
                    System.out.println("Did not find value.");
                }
                return;
            }
        }
    }

    public static void addNode() {
        int newNodeData = 0;
        String tmpStr = null;
        while (true) {
            tmpStr = getString("Enter an integer value to add:\t");
            if (tmpStr != null) {
                newNodeData = Integer.parseInt(tmpStr);
                avlTree.add(avlTree.getRoot(), newNodeData);
                return;
            }
        }
    }

    public static String getString(String message) {
        System.out.println(message);
        if (forInput.hasNext()) {
            return forInput.next();
        }
        return null;
    }
}

public class BinarySearchTree implements SearchTree {

    Node root;

    public BinarySearchTree() {
        root = null;
    }

    public BinarySearchTree(int data) {
        root = new Node(data);
    }

    public Node getRoot() {
        return root;
    }

    public void add(Node present, int addThis) {
        if(root != null)
        {
            if(present != null)
            {
                if (addThis < present.getData()) // If less
                {
                    // Go left
                    if (present.getLeft() != null) {
                        add(present.getLeft(), addThis);
                    } else {
                        present.setLeft(new Node(addThis));
                    }
                } else if (addThis > present.getData()) // If greater
                {
                    // Go right
                    if (present.getRight() != null) {
                        add(present.getRight(), addThis);
                    } else {
                        present.setRight(new Node(addThis));
                    }
                }
            }
        } else 
        {
            root = new Node (addThis);
        }
    }

    public void print(Node present) {
        if (present != null) {
            if(present.getLeft() != null)
            {
                System.out.println("Branching left");
            }
            print(present.getLeft());
            System.out.println("Returning and then Branching right");
            if(present.getRight() != null)
            {
                System.out.println("Branching right");
            }
            print(present.getRight());
            System.out.println("Returned to parent");
            present.printData();
        }
    }

    public Node find(Node present, int findThis) {
        if(root != null)
        {
            if(present != null)
            {
                if (findThis < present.getData()) // If less
                {
                    // Go left
                    if (present.getLeft() != null) {
                        return find(present.getLeft(), findThis);
                    }
                } else if (findThis > present.getData()) // If greater
                {
                    // Go right
                    if (present.getRight() != null) {
                        return find(present.getRight(), findThis);
                    }
                } else if (findThis == present.getData()) //If what we are looking for
                {
                    return present; //Return reference to the found Node
                }
            }
        }
        return null;  //Signal that it does not exist
    }

    public Node delete(Node past, Node present, int deleteThisData) {

        Node tmp = null;
        if(root != null) //Root must contain something
        {
            if(present != null) //Present must be non-null
            {
                if (deleteThisData < present.getData()) // If less
                {
                    if (present.getLeft() != null) { //If left is not null
                        tmp = delete(present,present.getLeft(), deleteThisData); //Go left down the branch and store whichever matches the node data
                    }
                } else if (deleteThisData > present.getData()) // If greater
                {
                    if (present.getRight() != null) {
                        tmp = delete(present, present.getRight(), deleteThisData);
                    }
                } else if (deleteThisData == present.getData())
                {
                    if(past != null)
                    {
                        if(past.getLeft().equals(present)) //If we've gone left (past.left and present are the same)
                        {
                            if(present.getRight() != null)
                                tmp = goRight(present.getLeft()); //Go all the way to the right after going left once
                            past.setLeft(tmp);
                        } else if (past.getRight().equals(present)) //Just the same if we've gone right 
                        {
                            if(present.getRight() != null) 
                                tmp = goLeft(present.getRight()); //Then go left once and then go right until the end of the branch to find replacement node
                            past.setRight(tmp);
                        }

                    }
                }
            }
        }
        return tmp;
    }

    protected Node goRight(Node present)
    {
        if(present.getRight() != null)
            return goRight(present.getRight());
        return present;
    }

    protected Node goLeft(Node present)
    {
        if(present.getLeft() != null)
            return goRight(present.getLeft());
        return present;
    }

}

CompilerError.jpg ^^ Screenshot of what I'm getting when I try to call the method from wthin itself (its calling the supeclass definition with Node type parameters).

Please reply soon. I need some help with this ASAP, this is due tomorrow morning and I cannot progress without this key information (I've been workong on it for three days now).

In your driver you are calling add etc BUT you don't say which object to call them on - so it defaults to the current object, which is the Driver class.

ie. you should be saying avlTree.printTree(); not just printTree(); and it will call the versions that are defined in AVLtree.

The problem with the Node types looks like (but I don't have time to check it all out)... you are getting a Node object from somewhere and trying to call methods from AVLNode on it - which fails because the superclass knows nothing a bout the subclass. If you happen to know that the object is really an AVLNode then use the cast recommended in the message so the Java compiler knows the calls are OK.

I think you're confused. I have a few methods within my driver which serve up a text menu for the user, and call their methods on the avlTree.

Check line #129. That is my printTree() method within driver which calls avlTree.print() (the method which prints the entire tree in order).

That is not the problem.

Yes, you're right. I was looking for reasons why a subclass method may not be being called... Without more time than I have I can't read all the code properly, but I hoped an "informed guess" may be more useful than nothing?

Hopefuly the second part of my post was more useful.

JC :)

Please, just show the functions/methods you are having issues with and the errors you are getting. Asking us to analyize 300+ lines of code is just not reasonable!

If you need an analysis of over 300 lines, consider Jlint first. Get that clean then follow advice about how to narrow down the issues.

[edit] Ok I solved it. I did think it was the following but I hadn't tested it.

Those methods are indeed getting called, I know so because I added a println at the opening line of the method. I was expecting the other println's to display too because I had one within each condition of my if statement. So no worries. Everything seems fine. This entire problem is solved now.

Alright, alright. I'm sorry I was in a bit of a panic and didn't think about that.
[old]
The problem is my AVLTree.add() (on line #3)and (presumably AVLTree.delete on line #35 suffers from the same problem). I'm trying to call them from the Driver within addNode() (line #163. If my guess is correct AVLTree.delete will have the same problem when I try to call it.

When I call AVLTree.add() on my AVLTree instance it winds up calling my BinarySearchTree.add() method (line #201). That is the root of the problem. My subclass methods are not being called even though the tree type is of AVLTree. Let me note that AVLTree inherits from BinarySearchTreeWithRotate (which inherits from BinarySearchTree, the details are unimportant, just know the hierarchy).

I've tried changing the signatures to match exactly (forgoing the AVLNode parameter types and casting them within the method), yet that does not work.

I should also say that that is not all one file. It does not appear that I can edit the code post anymore (couldn't find the button...) so its gonna stay that way. However there are exactly five classes in that block of code.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.