Вам нужна абстракция всякий раз, когда у вас есть класс, который вы не хотите применять всеми его методами. Те классы, наследующие его, будут вынуждены реализовать все эти методы, иначе вам нужно было бы объявить подклассы как абстрактные.
В дополнение к этому вы должны знать интерфейс, методы интерфейса не должны иметь тела, и хорошо, что ваш класс может реализовать столько, сколько вам нужно. Принимая во внимание, что вы можете наследовать только один абстрактный класс. Интерфейсы подобны контрактам. Какой бы класс не выполнял их, они должны обеспечить тело для всех своих методов.
Независимо от того, нужен ли вам абстрактный или интерфейс, или оба они действительно зависят от вашего дизайна и того, что вы хотите реализовать. Хотя это хорошая практика, чтобы заставить те классы, которые имеют общие методы для реализации одного и того же интерфейса (если вы ничего не знаете о теле каждого из методов) или абстрактном (если вы знаете, что тело какого-то, все или никого из методы)
Другим примером может быть, когда у вас есть абстракция или интерфейс, если вы добавляете что-то к ним, все подклассы или классы, которые им реализуют, должны следовать этим изменениям, это означает, что было бы легче получить изменения.
Посмотрите на this, this и this и open/close principle также.
Если вы строите что-либо новое, то корень должен быть интерфейсом или меньше, вы можете использовать абстрактный класс. – Prashant