I don't know this helps, but it's an analogy I've written about before.
One thing you have to remember is that you won't always be writing all the code yourself. There could be multiple departments, or third party vendors you buy code from. Maybe that third-party code generates an object you want to use - perhaps for a database connection, perhaps to draw something on the screen...whatever.
all you know is you call a method they provide, and you get an object that does what you need. you have two options:
1) write your code to expect a concrete class.
2) write your code to expect an object that implements an interface.
Both really look more or less the same on your end:
ThirdPartyClass myNeatObject = callToSomeMethod(params);
or
ThirdPartyInterface myNeatInterfaceObjcet = callToSomeMethod(params);
both look and work about the same...until...
a year goes by. The vendor says "we have a new library. It now runs faster, has a smaller memory footprint, and does more cool stuff.
You should start using it. It implements the same interface as the old version."
If you used the concrete class, you are screwed. Your code is expecting a ThirdPartyClass, but now the callToSomeMethod() returns a BetterThirdPartyClass object.
However, if you used an interface reference, the callToSomeMethod() returns an object that implements the same interface, so it just works.