OO programming talks about behaviour, and Interfaces define behaviour without specifying how that behaviour is implemented.
In a simple sense, consider the java.lang.Thread Class and the java.lang.Runnable Interface.
Java does not allow multiple inheritance, some once you have a base concrete class you're stuck with it. Therefore any class that wanted to run would be forced to extend
Thread and also it would not be possible to make other classes that do no already extend Thread to be able to run.
The Collections classes make heavy use of Interfaces so that you can swap one Collections implementation for another easily. If you force users to Pass ArrayLists to your methods than that works fine until someone wants to use a Vector, LinkedList, stack or even a class of their own.
The
JDBC API makes even heavier use of interfaces by defining database operations in terms of interactions between interfaces without very few concrete classes. This allows Driver writers to hide the concrete implementation under the interfaces and as long as they behave in the manner defined you never need to know the difference.
This just scratches the edge, but by defining code in terms of behaviour and not concrete implementations you provide looser coupling between the parts and open yourself up to greater flexibility in the future.