Conceptual implementation of inheritance

I am writing a spatial data structure, and I doubt what is the best implementation of NODE. According to my design, I have an abstract NODE object and three classes that inherit it: EMPTYNODE, FULLNODE, INTERNALNODE.

The first has no specific data.

The second has 1 link to a common element.

The third has 2 links to other nodes.

I found several ways to implement this situation (which I already encoded), but I can’t decide which is better.

The first solution I found is to use a single NODE class that potentially performs the entire operation this way:

private static class Node {
    private Elem elem = null;
    private Node left = null, right = null;
    public Elem getElem() {
        assert isFull();
        return elem;
    }

    public boolean isEmpty() {
        return elem == null && left == null;
    }

    public boolean isFull() {
        return  elem != null;
    }


    public boolean isInternal() {
        return elem == null && left != null;
    }
}

The second solution is to write an explicit division into classes, where each class offers only its own methods. Obviously, this way we are required to perform several casts to NODE objects.

private static abstract class Node {

    public abstract boolean isEmpty();

    public abstract boolean isFull();

    public abstract boolean isInternal();

}


private static class FullNode extends Node{

    private ITriangle elem;

    @Override
    public boolean isEmpty() {
        return false;
    }

    @Override
    public final boolean isFull() {
        return true;
    }

    @Override
    public final boolean isInternal() {
        return false;
    }

    public Elem getElem() {
        return elem;
    }
}

, , "isEmpty()" . .

private static abstract class Node {

    public abstract boolean isEmpty();

    public abstract boolean isFull();

    public abstract boolean isInternal();

    public abstract Elem getElem();

}


private static class Empty extends Node{

    @Override
    public boolean isEmpty() {
        return true;
    }

    @Override
    public final boolean isFull() {
        return false;
    }

    @Override
    public final boolean isInternal() {
        return false;
    }

    @Override
    public Elem getElem() {
        throw new AssertionError();
    }
}

?

?

.

+3
1

, . node, - , ?

, node , 3, , 1.

node, , node , node . :

public class Node {

   private enum NodeState {
      /* each state overrides specific methods to implement custom behaviour */
      FULL { public boolean isFull() { return true; } },
      INTERNAL { public boolean isInternal() { return true; } },
      EMPTY { public boolean isEmpty() { return true; } };

      /* the default behaviour */
      public boolean isFull() { return false; }
      public boolean isEmpty() { return false; }
      public boolean isInternal() { return false; }
   }

   private NodeState state = NodeState.EMPTY;
   private Elem      elem  = null;
   private Node      left  = null, right = null;

   public Elem getElem() {
      assert isFull();
      return elem;
   }

   /* TODO: constructors/mutators implement state changes go here */

   public boolean isEmpty() {
      return state.isEmpty();
   }

   public boolean isFull() {
      return state.isFull();
   }

   public boolean isInternal() {
      return state.isInternal();
   }
}

class Elem {
   /* implementation of this class */
}
+1

Source: https://habr.com/ru/post/1748145/


All Articles