The answer below does apply to any language that uses interfaces.
So an interface defines behaviour from a domain point of view, so you might want to think of it as an abstraction layer that filters out the details not required and ties up the usage to model behaviours and not instance or class type, example:
You have a very business heavy logic class that takes a request to process ticketing for a commute from location A to B.
You need to model (create class) a **car**, the current domain (understanding of usage) goes like
“I need to know a cars occupancy and max speed because I am using it to book tickets to fill and determine time of journey.”
At this point you have an understanding that a car might be abstracted to a vehicle, you don’t need to worry about color or engine displacement or other details.
So in the future the domain can be extended to add train, airplane, boat and rickshaws (classes that implement the vehicle interface).
All you care about is the behaviour from you domain perspective which is transportation and then you get the added benefit that you don’t have a hard dependency between tickets and cars and easier testing with mocking behaviour against a the interface.
Give me the domain that you are using interfaces for so I tailor the answer to it.