The basic idea behind inheritance is that objects can inherit the characteristics of other objects, which enables us to reuse more code. This reusing of code is often referred to white-box reuse, which basically means that the subclass not only has access to the interface and implementation but also to characteristics of its parent that otherwise would be private.
A downside of inheritance is the tightly coupled relationship between objects - which is usually something you want to avoid. Tightly coupled code is harder to change, more difficult to test, and not as reusable as loosely coupled code.
So before you decide to use inheritance make sure it’s the right tool for the job.
When to use inheritance
Inheritance should be used to model an “is a” relationship between multiple objects. A good example of this would be “A car is a vehicle”. In this case, the base class would be called
Vehicle and the subclass
It is important to make sure that the “is a” relation never changes during the lifetime of your application. The following relation “Employee is a Person” is true up to the point at which the Employee decides to leave the business. In this example
Employee should not inherit from
Person, their relationship should be modeled using composition.
Defining a Base Class
A base class can usually be split into two parts: interface and implementation. Due to the tight coupling, it’s important to keep those two parts as clean and separate as possible.
The fragile part of a class is the interface - if you have to make changes to the interface of your base class you also need to update every single class that inherits from your base class. Changes to your implementation on the other hand can be made at any time. Therefore, a well-designed base class with a clean separation of interface and implementation will cause fewer problems in the future.