Question

Hello I did a Binary Tree program for my Java Class and I got lots of points off for "No OOP Encapsulation" .. well I thought encapsulation was just using classes? What should I done different to enforce OOP Encapsulation? Below was my working code . Thanks for any input or advice

public class BinTree {


    private Node root;


    private static class Node{
            Node left;
            Node right;
            int value;


            Node(int newValue){
                    left = null;
                    right = null;
                    value = newValue;
            }


    }


    BinTree(){
            root = null;
    }


    public void insertNode(int value){
            root = insertNode(root, value);
    }


    private Node insertNode(Node node, int value){


            if (node==null){
                    node = new Node(value);
            }
            else{
                    if (value <= node.value){
                            node.left = insertNode(node.left, value);
                    }
                    else {
                            node.right = insertNode(node.right, value);
                    }
            }
            return(node);
    }


    public void treeWalk(){


            treeWalk(root);
    }


    private void treeWalk(Node node){


            if(node != null){


                    treeWalk(node.left);
                    System.out.println(node.value);
                    treeWalk(node.right);
            }


    }
}
Was it helpful?

Solution

@Marco13 is probably correct, though the only way to be sure what the marker meant is to actually ask him or her.


For what it is worth, I think your marker is incorrect here. Clearly, the outer class is properly encapsulated, and the nested class is private which means it is not visible outside of the outer class encapsulation boundary.

It is accepted Java practice that private inner classes do not necessarily need getters and setters for their fields.

Encapsulation is not a religion. It is used in Java for a purpose; i.e. to prevent implementation details from leaking. And declaring getters and setters also facilitates subclassing. But when the supposed purposes are moot (as they are here) use of encapsulation is not necessary.

If you want an apposite example, take a look at the Java source code for the standard LinkedList class:

Note that the Entry class does not have getters or setters ... and its fields are not declared as final either.

OTHER TIPS

When this was an assignment, the term "No OOP Encapsulation" probably refers to the fact that you did not use setters and getters for the fields of the Node class. So you should make left, right and value private, and offer methods for reading/writing the values of these fields accordingly.

(Note that "encapsulation" in this case also means that you do not have to create a method for modifying the value: This is only set in the constructor, and may not be changed later. So in fact, the value may (and should) even be private final.)

Wikipedia writes:

Under this definition, encapsulation means that the internal representation of an object is generally hidden from view outside of the object's definition. Typically, only the object's own methods can directly inspect or manipulate its fields.

In your case, the fields of the Node class are accessed from methods of class BinTree. Therefore, the Node is not encapsulated from the BinTree.

Your teacher might have wanted you to move the methods the access the node's state into the node class:

class BinTree {

    private Node root;

    private static class Node {
        Node left;
        Node right;
        int value;

        Node(int newValue) {
            left = null;
            right = null;
            value = newValue;
        }

        void insert(int newValue) {
            if (newValue <= value) {
                if (left == null) {
                    left = new Node(newValue);
                } else {
                    left.insert(newValue);
                }
            } else {
                if (right == null) {
                    right = new Node(newValue);
                } else {
                    right.insert(newValue);
                }
            }
        }

        void walk() {
            if (left != null) {
                left.walk();
            }
            System.out.println(value);
            if (right != null) {
                right.walk();
            }
        }

    }

    BinTree() {
        root = null;
    }

    public void insertNode(int value) {
        if (root == null) {
            root = new Node(value);
        } else {
            root.insert(value);
        }
    }

    public void treeWalk() {
        if (root != null) {
            root.walk();
        }
    }
}

Now, whether this is better design is somewhat questionable. Sure, the object oriented purist rejoices at the shorter parameter lists, and that all methods only access the fields of this, but a pragmatic programmer will find the duplicated null checks just as bad, or possibly worse than, the lack of strict encapsulation in your approach.

Personally, I consider encapsulation (or more generally information hiding) an indispensable technique for writing all but the most trivial of programs. But I disagree that the proper size of a capsule need always be a single object. In your original code, the capsule surrounds the entire tree, and that's good enough for me.

The idea of OOP is to make code more reusable and more object like, when you are creating an object you want to be able to use all the functions of that object, this also includes accessing data. The problem comes down to creating more than 1 type of object and accidentally overriding the value of data. This is why you encapsulate. here is an example of encapsulation

private int health;

public void getHealth(){
 return health;
}

public int setHealth(int h){
 this.health = h;
}

you ask why bother having 2 methods for this property? when you instantiate the class, you don't want to directly access its property but do it indirectly to avoid overriding its default value. You set the property to private so that no class can call it directly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top