views:

415

answers:

6

By extending class Vector, Java’s designers were able to create class Stack quickly. What are the negative aspects of this use of inheritance, particularly for class Stack?

Thanks a lot.

+3  A: 

Well, Stack should be an interface.

The Stack interface should define the operations a stack can perform. Then there could be different implementations of Stack that perform differently in different situations.

But, since Stack is a concrete class, this cannot happen. We are limited to one implementation of a stack.

jjnguy
+6  A: 

One problem is that Stack is a class, not an interface. This diverges from the design of the collection framework, where your noun is typically represented as an interface (e.g., List, Tree, Set, etc.), and there are specific implementations (e.g., ArrayList, LinkedList). If Java could avoid backward compatibility, then a more proper design would be to have a Stack interface, then VectorStack as an implementation.

A second problem is that Stack is now bound to Vector, which is generally avoided in favour of ArrayLists and the like.

A third problem is that you cannot easily provide your own stack implementation, and that stacks support very non-stack operations like getting an element from a specific index, including the potential for index exceptions. As a user, you may also have to know if the top of the stack is at index 0 or at index n. The interface also exposes implementation details such as capacity.

Of all the decisions in the original Java class library, I consider this one of the more peculiar ones. I doubt that Aggregation would have been much more expensive than inheritance.

Uri
Sun recommends using a `Deque` (like `ArrayDeque`) instead of Stack in Java 6 and newer.
R. Bemrose
@Bemrose: That is true. However, I am actually not a big fan of that because it exposes interface methods to take stuff out from both sides. The DE nature seems like an implementation detail to me. I guess I'm an API purist. As an aside, I always hated how STL coined the "deque" acronym, since in most accents it is pronounced like "dequeue", leading to some confusion.
Uri
+5  A: 
polygenelubricants
But what if the object you put on the stack is modified while its on the stack? Either we have to make stack take a deep copy with every push or we have to look more critically at what LIFO means.
CurtainDog
+3  A: 

Having Stack subclass Vector exposes methods that are not appropriate for a stack, because a stack is not a vector (it violates the Liskov Substitution Principle).

For example, a stack is a LIFO data structure yet using this implementation you can call the elementAt or get methods to retrieve an element at a specified index. Or you can use insertElementAt to subvert the stack contract.

I think Joshua Bloch has gone on record as saying that having Stack subclass Vector was a mistake, but unfortunately I can't find the reference.

John Topley
See polygenelubricant's quote from Effective Java, written by Bloch.
Mark Peters
@MarkPeters Thanks!
John Topley
RE: LSP - not true at all. Where ever you have a java.util.vector you can substitute a java.util.stack without changing the behaviour of the function. For the record I believe inheritence of behavoiur is evil, but Stack subclassing Vector is one of the *mildest* violations of this that I've encountered.
CurtainDog
+2  A: 

In addition to the main valid points mentioned above, another big problem with Stack inheriting from Vector is Vector is completely synchronized, so you get that overhead whether you need it or not (see StringBuffer vs. StringBuilder). Personally I tend to use ArrayDeque whenever I want a stack.

M. Jessup
+1  A: 

It violates the very first rule we all learned about inheritance: can you, with a straight face, say that a Stack IS-A Vector? Clearly not.

Another more logical operation would be to have used aggregation, but the best option IMO would be to have made Stack an interface which could be implemented by any appropriate data structure, similar (but not exactly the same) to what the C++ STL does.

Graphics Noob