Почему интерфейсы упрощают жизнь?

1,00
р.
Ранее никогда не писал собственные интерфейсы для "упрощения жизни". Почему? Что в них такого интересного?
В комментариях попросили добавить в вопрос мои знания и область работы. Пишу android приложения и... Все. Об интерфейсах не знаю ничего, только то, что можно класс от интерфейса наследовать и переопределить методы. Но зачем? Смысл интерфейсов?
Спасибо за замечательные ответы!

Ответ
Интерфейс предоставляет контракт, который должны выполнять все классы, реализующие этот интерфейс, и является абстракцией, показывающей что объект может делать, но как он этот делает - не важно.
На практике это приводит к следующему:
При использовании интерфейсов появляется возможность заменять один класс, реализующий интерфейс, на другой класс, реализующий этот же интерфейс, без переписывания всего кода. Например, если методу передаётся Map:
public void handle(Map map) { ... }
то не придётся менять описание метода, если потребуется использовать TreeMap вместо HashMap. Аналогично если метод возвращает Map: он может начать возвращать TreeMap вместо HashMap, и трагедии библейских масштабов при этом не случится, так как код, работающий с возвращенным этим методом значением, имеет дело с Map. Это увеличивает гибкость кода: проще переключаться с одного источника данных на другой и с одной реализации на другую. Также это полезно при тестировании, так как позволяет использовать Mock-объекты вместо настоящих.

Если нужно одинаково обрабатывать коллекции элементов (например, ArrayList и Set, возвращаемый методом keySet() у HashMap), то достаточно описать метод так:
public void handle(Collection elements) { ... }
Использование generics-типа здесь для большей реалистичности. Без использования интерфейса пришлось создавать два метода:
public void handle(ArrayList elements) { ... }
public void handle(Set elements) { ... }
И либо дублировать код, либо, например, во втором методе создавать ArrayList, добавлять в него все элементы из Set и вызывать первый метод.

Также использование интерфейсов позволяет объединить разные объекты, реализующий один и тот же интерфейс, в один список и одинаково их обрабатывать:
public interface Animal { public void feed() }
public class Dog implements Animal { public void feed() { ... } }
public class Cat implements Animal { public void feed() { ... } }
List animals = new ArrayList<>() animals.add(new Cat()) animals.add(new Dog()) for (Animal animal : animals) { animal.feed() }
Без использования интерфейса пришлось бы городить "if-else" (или "switch-case") с отдельной реализацией логики для каждого типа животных.