The key principles in OOP are encapsulation, cohesion, and coupling. Encapsulation is a protection mechanism. You restrict access to the internals of a class (or an instance of a class) from external actors. Cohesion describes how related the methods/properties of the class are. SRP is an expression of cohesion. Coupling is how much interaction classes (or instances of them) have with each other. You need some, but want them loosely coupled. Dependency injection is one way of keeping your classes loosely coupled. For example, you inject dependencies, not create them internally so that the consuming class doesn't have intimate knowledge of how the class it is dependent on is created (and thus have to change if the creation logic changes). Inheritance isn't strictly necessary for OOP but it allows related classes to share behavior; it's defined by an is-a relationship between two classes, for example, a Car
is a specialization of a Vehicle
.
Your idea of having all classes inherit from a single base class, other than a simple object
class to give them common behaviors like equality and duplication, is a violation of the loose coupling principle and certainly is a bad example of inheritance. A storage mechanism is NOT an app. An app might have a storage mechanism, so it would be an example of a has-a relationship or composition rather than inheritance.