Dependency injection is an example of an inversion of control software design pattern. Inversion of control is a principle that involves having a generic and reusable framework to make calls and delegate to more custom code. In Drupal 7, an example of this is the menu system. A request comes in and is matched to a route and then Drupal loads the module file and calls the appropriate function. Dependency injection specifically allows you to define when your class needs a dependency and have those needs fulfilled by the system.
When creating new functionality in Drupal 8, you write your dependencies into your class constructor and, when the system creates your class, they are passed into it.
A key advantage to using dependency injection is that you do not have to know how to instantiate the services that your class depends on. Take, for example, a simple database connection. In order to connect to the database you need the appropriate driver, username, password...