Ваш интерфейс определяет контракт, который должен быть выполнен для принятия объекта; Ваш абстрактный класс определяет контракт, который должен быть выполнен, И определяет некоторые конкретные детали реализации.
Думайте об этом так; если вы думаете, что когда-либо возможно, что кто-то захочет выполнить этот контракт не так, как это делает набросок абстрактного класса (скажем, с другой реализацией базового типа данных), то вы должны иметь и интерфейс, и абстрактный класс, который реализует это.
Практически нет необходимости использовать абстрактный класс и интерфейс; Ваш риск, связанный с этим подходом, в первую очередь связан с тем, что более поздний кодер сталкивается с интерфейсом, не понимая, что существует абстрактный класс, реализующий интерфейс, и создавая целую реализацию с нуля там, где это не нужно. Я бы сказал, что это можно обойти, указав в документации по интерфейсу, что в вашем абстрактном классе есть реализация интерфейса по умолчанию; хотя некоторые стандарты кодирования могут не одобрять эту практику, я не вижу никаких реальных проблем с ней.