Интерфейс это контракт . Указывая implement (перевод - выполнить) ты гарантируешь, что в классе будет определенные методы с определенными входными и выходными параметрами. Используются интерфейсы для внедрения зависимостей (буква D в SOLID). То есть, можно указать, что некий метод принимает классы, подписанные на некий контракт и подпихивать туда условно любой из этих классов по необходимости. Например, когда у тебя есть несколько классов, которые делают одну и ту же вещь разными способами (квадратное уравнение можно решить через дискриминант, а можно через Виета) - можно почитать про паттерн Стратегия.
Абстрактный класс это класс . Это значит, что он умеет все, что умеют обычные классы + указывать метода без реализации. Абстрактными классом происходит расширения дочернего класса родительским. Получается, что унаследовавшись от абстрактного класса можно получить обязательства реализации некоторых методов + реализованные метода + атрибуты класса и тд. Используем их для выделения какого-то общего кода у группы родственных классов, с возможностью указать какие методы должны быть реализованы в дочернем классе.
При этом никто не мешает эти вещи использовать одновременно, они друг другу не противоречат.