Linked list node implementation with maximum code reuse Currently as an exercise to practicing SOLID principles and basic data structures, I am trying to implement linked list type structures with as much code reuse as possible. Currently, I have:

package structures.linked;

public class SingleNode&lt;T&gt; {

    private T data;
    private SingleNode&lt;T&gt; next;

    public SingleNode(T data, SingleNode&lt;T&gt; next) {
        this.data = data;
        this.next = next;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public SingleNode&lt;T&gt; getNext() {
        return next;
    }

    public void setNext(SingleNode&lt;T&gt; next) {
        this.next = next;
    }

}


and...

package structures.linked;

public class DoubleNode&lt;T&gt; extends SingleNode&lt;T&gt; {

    private DoubleNode&lt;T&gt; prev;

    public DoubleNode(T data, DoubleNode&lt;T&gt; next, DoubleNode&lt;T&gt; prev) {
        super(data, next);
        this.prev = prev;
    }

    public DoubleNode&lt;T&gt; getPrev() {
        return prev;
    }

    public void setPrev(DoubleNode&lt;T&gt; prev) {
        this.prev = prev;
    }

    public DoubleNode&lt;T&gt; getNext() {
        return (DoubleNode&lt;T&gt;) super.getNext();
    }

    public void setNext(DoubleNode&lt;T&gt; next) {
        super.setNext(next);
    }
}


It seems to me that getNext() inside of DoubleNode&lt;T&gt; is a violation of Liskov's substitution principle. Is this the case? Is there a better way to implement this while still reusing the code in SingleNode&lt;T&gt; and without breaking SOLID principles?
Usually linked lists keep most methods as private and the actual nodes cannot be accessed by the public API.

If you start implementing the different methods for adding, removing, etc. you might have on singly and doubly linked lists, you will find the implementations are quite different.  So much so that I think it would be simpler to have two completely separate classes.  They could both implement the java.util.List interface.  I'm a huge fan of code reuse, but I don't think it's a good idea in this case.  Trying to share some code between singly and doubly linked list would end up making the code less readable.  This is just a guess since I have not actually tried implementing them.