Первое: интерфейсы принадлежат не уровню реализации, а уровню использования.
Что значит?
У вас есть проект самолета.
Есть транспортная компания перевозящая грузы.
Есть пассажирская - соответственно перевозящая пассажиров.
у транспортной есть некий шаблон под названием транспортное средство. Все что подпадает под этот шаблон может компанией использоваться.
У пассажирской - все что подпадает под шаблон "средство перевозки пассажиров"
Т.е. по большему счету им не важно что будет самолет или автобус.
Вы хотите, что бы ваши самолеты использовались. Вам нужно реализовать интерфейс (шаблон использования) грузоперевозчик. Для одной компании. Для пассажирской вы можете реализовать шаблон пассажироперевозчик.
Т.е. интерфейс это некая договоренность, способ использования. И он лежит не на уровне библиотеки (т.е. на уровне реализации класса), а на уровне более высокой логики. (транспортное средство)
Интерфейс становиться неким шаблоном между двумя частями системы. Он достаточно стабилен. Из этого мы получаем разделение большой системы на две части. и соответственно мы можем разрабатывать раздельно эти части, не боясь что-то нарушить в другой части.
По части использования. Интерфейсы очень широко применяются. Даже в небольших проектах. Они разбивают на части систему, что очень полезно для построения прозрачных моделей. Также это дает возможность работать нескольким людям над одним проектом (или одному. Над частями проекта)
Это дает возможность Сосредотачиваться на логике проекта, оставляя реализация на "позже" - делая простые затычки для тестирования.
В примере с животными. Есть зоопарк где животные. По большей части они работают с интерфейсом животные (кормят, ограждают и т.е.) И все что подпадает под интерфейс животное легко там содержится. Если им привезти новое животное, они его посадят в клетку, будут кормить и показывать детям. Т.е. Животное - это скорее договоренность, а не сущность. (для зоопарка)