A class LinkedList exists with functions such as add_first(), add_last(), add_after(), remove_first(), remove_last() and remove()
Now there is a class Stack that provides functionalities such as push(), pop(), peek() or top(), and to implement these methods it extends the LinkedList class methods. Is this a violation of Liskov Substitution Principle?
For example, consider the case add_after() to add a node at the nth position of a Linked List. This can be done in the base class but not in the Stack class. Are postconditions being weakened here or do you modify the add_after() method to add to the top of the Stack?
Also, if not a violation, is this bad design? And how would you implement the Stack functionality using the LinkedList class?
Best Answer
No. It is perfectly fine to add methods in a subtype.
This is a violation of the LSP. The LSP says that instances of a subtype must be substitutable for instances of a supertype without changing the desirable properties of a program. If a subtype removes a method, then any code that calls that method will crash (or get a
NoMethodError
exception, or something along those lines). Clearly, "not crashing" is a desirable property.Modifying the
add_after()
method in this way is a violation of the History Rule (the most important of the rules!) and thus doesn't help fixing the violation of the LSP.By using composition.
NOTE: Everything I wrote above only applies to languages which confuse subtyping and subclassing! The LSP is about subtyping, not subclassing. In a language which does not confuse the two, it would be perfectly acceptable to make
Stack
a subclass ofLinkedList
, as long as you do not make it a subtype ofLinkedList
.