Необходимость цепочки наследования, как правило, сомнительна.
Однако конкретный сценарий объединения абстрактного базового класса с интерфейсом .. Я вижу это так:
Если у вас есть такой абстрактный базовый класс, у вас также должен быть соответствующий интерфейс. Если у вас есть интерфейс, используйте абстрактный базовый класс только в тех случаях, когда цепочка наследования имеет смысл.
Тем не менее, если я пишу библиотеку, и это является частью моего API / Framework, я обычно буду включать "реализацию по умолчанию", которая может использоваться в качестве базового класса. Он будет реализовывать методы интерфейса наивным, общим способом, где это возможно, и оставит остальное наследникам для реализации / переопределения по мере необходимости.
Это просто удобная функция библиотеки, которая помогает людям, которые хотят реализовать интерфейс, предоставляя функциональный пример, который может охватывать большую часть того, что им нужно реализовать.
Короче говоря, интерфейс более ценен, чем базовый класс, но базовый класс может сэкономить много времени и уменьшить количество ошибочных реализаций интерфейса.