I have two C++ classes: Sequence, which is just like std::vector, and File, which is a Sequence of strings that represents a file on the machine.
Deriving File from Sequence is a no-brainer. Its behavior is exactly the same, but with the added functionality of reading and writing files. The File-specific functionality is implemented easily, without the need for Sequence‘s data members to be marked as protected. Instead, they can be private, and File can use Sequence‘s public interface. Happy times all around.
I want to make an Array class that internally manages dynamically-allocated memory. An Array object cannot be resized; the size is specified in the constructor.*
Here’s where things get arguable.
Concept-wise, it makes sense to derive Sequence from Array. Just as a File is a Sequence with the added functionality of reading and writing files, Sequence is an Array with the added functionality of resizing on-demand.
But there’s a key difference: The resizing functions require direct access to the memory Array is managing. In other words, the previously-private members must now be protected.
Using protected members instead of private ones destroys encapsulation. The link between Array and Sequence is the only one that requires it; other classes in the works can just use their parents’ public interfaces. In this sense, it’s a bad idea to derive.
You could argue that people who want arrays can just use Sequence and ignore the resizing functionality. But then again, you could just use File and ignore the read/write functionality. It would be like buying a laptop but never moving it from your desk. It simply doesn’t make sense.
What’s the best move: To derive, and potentially destroy encapsulation; to make Array a completely free-standing class, and have to pointlessly re-implement a lot of functionality; or to forget about Array completely and just make people use Sequence?
*Note that this is a project for fun and education, so the practicality of having a non-resizable dynamically-allocated array is beside the point.
Well, deriving
SequencefromArraywith public inheritance in your case is definitely bad idea (as deriving square from rectangle). In the terms of Object-Oriented Programming, Sequence IS NOT an Array, sinceArrayhas a property thatSequencedoes not have, and it’s:An Array object cannot be resized. If you make a derivation, it will break the Liskov substitution principle.In your case, as you want to implement some functionality, already existing in another class, I would suggest you to use either private inheritance (which means inheritance of implementation), or composition, e.g. storing an instance of
Arrayin private zone ofSequenceand using it for inner implementation.UPD: However, implementing
Sequencewith usage of anArrayalso seems to me quite problematic. Maybe it would by much better to create some abstract base classContainerthat would implement the common functionality ofSequenceandArray, and then derive both these classes from it.