Интерфейсы (в общем) обеспечивают абстракцию и инкапсуляцию.
Абстракция означает, что клиенту не нужно знать больше, чем в интерфейсе, чтобы использовать объект.
Инкапсуляция означает, что клиент не может знать больше, чем находится в интерфейсе.
Вместе это называется скрытием информации.
Так что, в некоторой степени, вы правы, что каждыйКласс обеспечивает собственную реализацию, поэтому вам не нужен интерфейс.Однако в этом случае клиент становится зависимым от реализации.К сожалению, в реальном мире реализация постоянно меняется.По мере изменения реализации весь зависимый код придется менять.
Используя интерфейс, клиент зависит только от того, что указано в интерфейсе, а не от фактической реализации.Таким образом, реализация может измениться, и клиентский код не обязательно требует изменения.Конечно, нужно позаботиться о том, чтобы сам интерфейс не изменился.
Скажем, у вас есть коллекция объектов.Затем вам нужно было отсортировать эти объекты в некотором порядке.Если вы реализовали свою коллекцию в виде дерева, то код для сортировки полностью отличается от того, если бы вы реализовали связанный список.Клиентский код, подвергающийся воздействию этих реализаций, потребует изменения, если какие-либо детали этих реализаций изменятся.
Если, с другой стороны, вы создаете интерфейс, скажем, Collection, который обещает, что любая реализация сможет сортировать себяно он не говорит вам, как он будет сортировать, тогда ваш клиентский код может зависеть от возможности сортировки, не зная деталей сортировки.
Вы можете легко изменить тип коллекции и алгоритм сортировки, не влияя на клиентакод.