Абстрактные классы позволяют переносить код / данные, которые затем можно использовать в унаследованных классах. Они отлично подходят для этого, но очень редко используют наследование. Наследуйте от класса только в том случае, если новый класс абсолютно взаимозаменяем с абстрактным.
Интерфейсы не содержат кода.
Я предпочитаю кодировать интерфейсы всякий раз, когда это возможно. Я также хотел бы, чтобы эти интерфейсы были как можно меньше. Это оставляет мне гибкость, чтобы поменять основную имплементацию на более позднее время.
Если вы кодируете абстрактный класс, то сложнее поменять реализацию на более позднее время.
Вы можете применить интерфейс (или несколько небольших интерфейсов) к абстрактному классу. Похоже, это может быть вашим лучшим подходом.