Imagine that you're making a GUI and have a DataViewList
class that is a widget that displays rows of data (like this for example). You have methods AddRow(std::vector<std::string> row)
, DeleteRow(std::vector<std::string> row)
and AddColumn(std::string name)
, DeleteColumn(std::string name)
.
Now lets say you want to make a new class that displays a music playlist. It has predetermined columns (Title, Album, Year) and you don't want to ever add any new columns or delete existing ones. Also you want to be able to add Song
objects to the list in a single method call, so you need a method that can do that. How do you implement such a class?
The most basic idea is to just create a new class MusicPlaylsit
that inherits publicly form DataViewList
and add the predetermined columns in the constructor. Then overload the AddRow
methods such that it accepts Song
objects as an argument. This approach has a big problem: Someone could call MusicPlaylist::AddColumn
or other methods that are incompatible with the logic of the MusicPlaylist
class. Since MusicPlaylist should only ever have the three predefined columns, then there shouldn't be a way to add or delete columns (or access any other incompatible base class methods such as the base class non-overloaded AddRow method).
To solve this, I can use composition instead of inheritance and re-implement any methods that I may want to use. In my opinion this is a bad idea because if I want to change something in the future, it's more difficult than inheritance because I cant override the base class methods.
Another option is to inherit as protected
. This prevents using incompatible base class methods AND allows for overriding in case of future inheritance. The problem is, now I have to explicitly declare every method I want to use as public with using
, which seems to be against the whole point of object oriented programming (being able to change something in a deep base class and still have any inherited class be able to use it) because newly added public methods in DataViewList
will not be visible in MusicPlaylist
or any classes that inherit from it until they have been explicitly made public.
So my question is: which pattern should I use when creating a new class that has an "is a" relationship to a base class, but is only partially compatible with it's methods?
Thanks
Aucun commentaire:
Enregistrer un commentaire