What makes interfaces useful is not the fact that "you can change your mind and use a different implementation later and only have to change the one place where the object is created". That's a non-issue.
The real point is already in the name: they define an interface that anyone at all can implement to use all code that operates on that interface. The best example is java.util.Collections
which provides all kinds of useful methods that operate exclusively on interfaces, such as sort()
or reverse()
for List
. The point here is that this code can now be used to sort or reverse any class that implements the List
interfaces - not just ArrayList
and LinkedList
, but also classes that you write yourself, which may be implemented in a way the people who wrote java.util.Collections
never imagined.
In the same way, you can write code that operates on well-known interfaces, or interfaces you define, and other people can use your code without having to ask you to support their classes.
Another common use of interfaces is for Callbacks. For example, java.swing.table.TableCellRenderer, which allows you to influence how a Swing table displays the data in a certain column. You implement that interface, pass an instance to the JTable
, and at some point during the rendering of the table, your code will get called to do its stuff.