The way I can do that is by having a parent class called SomeParentClass
that have a virtual method called printInfo()
, and then I would make the classes data types that can be present in the array inherit from this class and override the printInfo()
method, and then I can create an array of type SomeParentClass*
.
Is there anything wrong with this approach?
There's absolutely nothing wrong with that at all (although I'd very strongly recommend avoiding pointers and arrays, and instead choose something like std::deque
with std::unique_ptr
or std::shared_ptr
so that you're not writing code which needs to deal with memory management).
From a language-agnostic 'OO' perspective, this is exactly the kind of scenario which inheritance is expected to be used with.
I'm asking because I have read that a class should represent an entity (for example: BankAccount
, Car
, House
, Student
, etc.), but SomeParentClass
doesn't represent an entity. I have also read that the relationship between a parent class and a child class is an "Is-A" relationship, but the classes that will inherit from SomeParentClass
are not SomeParentClass
(in the same way that a Car
is a Vehicle
for example).
I can think of a few scenarios where this might be reasonable advice, although I can think of many more scenarios where this advice is misleading or wrong. There have been too many books, blogs and tutorials written over the years which attempt to explain OO in terms like this, and most of the time they're written by people whose own understanding of OO is misguided (At least from the point of view that it doesn't match up with Alan Kay's original definition of the term 'object oriented programming', which has nothing to do with entities).
Firstly, there's absolutely no requirement whatsoever that a class should represent a data entity. Sticking to this kind of mantra as a hard rule can very easily lead towards a very narrow and misguided way of thinking about code structure where any kind of behaviour which may happen to be related to a particular data entity belongs to that entity, resulting in heavily bloated classes containing dozens of methods which have little or no relationship to each other. This mindset frequently results in the "God Object" anti-pattern as described here: https://en.wikipedia.org/wiki/God_object
Class design is completely different to Entity Modelling - if you conflate 'entities' with 'classes' then you're also in danger of losing out on logical separation between different layers and modules in your code.
For example, in a layered/tiered architecture, you may have simple entity structures which contain no behaviour and are simply used to support CRUD operations to/from a persistence store. Typically, classes containing your core business logic should have no knowledge of persistence. If you follow the view that classes should be entities, then you can end up with 'business logic' classes which also contain a lot of methods unrelated to the business logic such as Read
or Save
, at which point the code loses any kind of clear structure or separation.
The key to object-oriented programming lies behind designing classes around logical separation and grouping of related behaviour (i.e. functions/methods).
That is to say, in many (but not all) circumstances, restricting your use of classes just to representing entities doesn't provide a useful structure to your code, and can sometimes be counter-productive.
If a class contains methods which have no relationship to each other and which serve completely unrelated requirements, then it's an indication that you've got a class which is doing too many things - but this is exactly what you're likely to end up with if you treat entities as classes. Most of the time the way to arrive at clean, modular code is to split unrelated methods across different classes which probably don't map neatly on to any entities in your problem domain.
On the other hand, Entity modelling is all about identifying and grouping logically related data attributes, and logical relationships between grouped data. In many cases, the criteria you might use when deciding whether to create a grouping of attributes into an entity (such as 3NF/BCNF) will be completely different to the criteria when deciding to create a grouping of behaviours into a class; for this reason, it's best to avoid blurring the lines between the concept of a data entity versus the concept of a class.
Printable
, you can say that aBankAccount
is aPrintable
object.