Абстрактные классы в основном используются в том случае, если какую-то часть кода можно описать в дочернем классе, но для того чтоб эта часть приобрела смысл, нужна конкретика: дополнить общую картину подробностями в виде методов или полей. Если вы присмотритесь к абстрактным классам в современных фреймворках, то увидите что сам по себе абстрактный класс не имеет смысла. Например, если создать объект такого класса оператором new, то этому объекту всё равно будет чего-то не хватать и именно это что-то и добавляют конкретные классы.