Абстрактные классы рекомендуется использовать в следующих ситуациях:
- Нужно определить общий функционал для родственных объектов. 1
- Необходимо спроектировать большую функциональную единицу, которая содержит много базового функционала. 1
- Нужно, чтобы все производные классы на всех уровнях наследования имели некоторую общую реализацию. 1
- Проект уже частично написан, и известно, что выбранные классы будут часто меняться и дополняться новыми методами и полями. 5
Интерфейсы лучше использовать в таких ситуациях:
- Нужно описать определённую логику, которую должны поддерживать не связанные между собой объекты. 5
- Необходимо привести к одному типу группу объектов и гарантировать схожую функциональность. 5
- Нужно добавить какой-то маркер, который будет говорить о том, что выбранные классы поддерживают определённую логику. 5
- Необходимо использовать множественное наследование типа. 5
Таким образом, принцип выбора между абстрактными классами и интерфейсами: если классы относятся к единой системе классификации, то выбирается абстрактный класс, иначе — интерфейс. 1