Наследование как средство многократного использования кода - действительно очень плохой выбор. Учтите, что каждый класс на языках .NET имеет единственный слот наследования, куда может идти код. Следовательно, для каждого класса следует выбирать мудро, наследовать ли он от чего-то другого или нет.
Обычно говорят, что наследование описывает отношение "is-a" , где, поднимаясь по цепочке наследования, мы достигаем более высоких уровней абстракции.
Первый вопрос всегда должен заключаться в том, не является ли отношение *1011* "can-act-as" недостаточным. В этом случае описание отношений через интерфейсы часто является лучшим выбором. Во-вторых, при добавлении абстракций вопрос должен заключаться в том, может ли немало кода работать с этими абстракциями, чтобы удовлетворить функции, которые вы ищете.
Если вряд ли есть какой-либо код, использующий эти абстракции, то они, скорее всего, сами по себе бесполезны. Опять же, стоимость абстракции обычно ниже для интерфейсов, чем для базовых классов.
Итак, в итоге
- Отношения "можно действовать как" обычно достаточно - тогда вам не нужно идти на отношения "есть"
- Слот наследования драгоценен - его можно использовать только один раз.
- Существует намного больше способов повторного использования кода, чем наследование от класса
- Базовые классы и интерфейсы являются абстракциями: убедитесь, что ваш код действительно может их использовать. Если ваш интерфейс реализован только одним классом, ваша абстракция может оказаться бесполезной и легко вводиться, когда это становится необходимым.
- Если существует необходимость в абстракции, штраф на интерфейсах ниже, чем на базовых классах.