То, о чем все забывают упомянуть, это обратная совместимость. Вы можете добавлять новые методы в базовый класс, не нарушая существующих клиентов, в то время как вы не можете изменять существующие интерфейсы, не затрагивая их.
Существуют альтернативы, позволяющие избежать проблем совместимости с интерфейсами. Например, вы можете создать новый интерфейс, который наследуется от старого, когда вы добавляете новые расширения для своего приложения. Но у этого есть недостаток вздутие живота вашей архитектуры с такими типами, как IClientInterfaceV2 и IClientInterfaceV3.
Мое личное предложение было бы пойти с подходом, подобным предложенному scwagner , и создать как базовый класс, так и интерфейс. И включите предупреждение для пользователей интерфейса, в котором говорится, что будущие версии могут нарушить их реализацию и что стратегия наследования базового класса является рекомендуемой, чтобы избежать будущих проблем совместимости.