FAQ 8.11 Should Stack inherit from List?Probably not. It is tempting to inherit Stack from List to reuse the List class (for example, if List were a linked list). However, even if List is an abstract class, it will normally define member functions that aren't natural for a Stack, and if List provides member functions that class Stack doesn't want to support, inheritance would be wrong. For example, the public: interface to a typical Stack class might look like the following (some or all of these member functions may be virtual; this is a stack of integers see FAQ 25.02 for how to make it a template). class Empty { }; class BadPosition { }; class Stack { public: void push(int item) throw(); // Push another item onto this int pop() throw(Empty); // Remove the top item from this int top() const throw(Empty); // Peek at the top item of this unsigned size() const throw(); // Returns the number of items }; In contrast, the public: interface of a typical List class might look like the following (some or all of these member functions may be virtual; this is a list of integers see FAQ 25.02 for how to make it a template). class List { public: void prepend(int item) throw(); void append(int item) throw(); void removeFirst() throw(Empty); void removeLast() throw(Empty); void insertAtPosition(int item, unsigned position) throw(BadPosition); void removeAtPosition(unsigned position) throw(BadPosition,Empty); int& operator[] (unsigned index) throw(BadPosition,Empty); int operator[] (unsigned index) const throw(BadPosition,Empty); unsigned size() const throw(); void setSize(unsigned newSize) throw(); unsigned countMatches(int itemToMatch) const throw(); unsigned findPositionOfMatch(int item) const throw(); }; If Stack were to inherit from List, Stack would need to support all the member functions that are in class List, including member functions to access, insert, and/or remove elements at an arbitrary position within the Stack. If these member functions are considered inappropriate for Stack, then Stack should not inherit from List and should use composition instead (see FAQ 5.09). Remember: do not confuse substitutability and code reuse. Just because Stack may use the bits and code from List does not imply that Stack is substitutable for List. The substitutability relation is governed by behavior, not code reuse. When evaluating a potential inheritance relationship, the only criterion should be substitutability. |