
Зачем нужны абстрактные классы без абстрактных методов? Например, чтобы запретить создавать объекты этого класса. Допустим есть класс «животные» от которого наследуются «кошки», «белки», «коровы» и т.д. По логике нельзя создать объект «животные». Должно быть какое-то конкретное животное: кошка, белка, корова. «Животные» - это абстракция.
Все абстрактные методы должны быть реализованы в классах-наследниках. Зачем нужны абстрактные методы? Для того чтобы указать, что для корректной работы объекта должны быть обязательно реализованы методы, указанные в абстрактном классе. Причем, абсолютно не важно как они будут реализованы для каждого наследника. Например, каждое животное должно питаться. Однако, все животные питаются по-разному: кошки едят мышей; белки – грибы, орехи, шишки; коровы – траву. Поэтому метод eat() выносится в абстрактный класс как абстрактный метод, не имеющий реализации. Теперь в каждом классе-наследнике обязан быть метод eat(), и каждый класс будет иметь свою реализацию этого метода.