Dependency Inversion Principle

When designing a class, high level class depend on the low level class to implement the primary operation, ideally our system should look like a tree of classes. We use composition for this, High level class contains low level class implementation.
class HighLevel
LowLevel lowLevel;
...That design comes with a problem, when LowLevel class need to be changed or to be extended, all the parent needs to be changed to, because they are highly coupled together and as we know, coupling is EVIL.
Dependency inversion principle, states:
High-level modules should not depend on low-level modules. Both should depend on abstractions.
and
Abstractions should not depend on details. Details should depend on abstractions.
This is example before using the principle
And this is good example after implementing the principle
In the good example, Every time we want to add new implementation of work, we just add new class implementing Worker interface, the Company class don’t care how the low level detail work, only caring about the low level contract with the interface.
