I have decided to start doing small coding projects on my own that focus on code quality instead of code quantity and have a question about the use of abstract classes.
In OO world, abstract classes used to impose some design & implementation constraints. Nothing more. You never have to use abstract classes in any case. But there might be cases that you better impose those constraints. So what are them? Let's look at by comparing it's oo-counterparts.
Abstract classes vs interfaces
As you know, these are two of the primary concepts of inheritance.
Basically, interface is used just to declare that you're willing to inherit the underlying service and that's it. Contains no implementation & has no functionality. In that sense, interface is abstract. That's why it's a more a design constraint than an implementation constraint. Think of a headphone jack on a speaker. Each headphone needs to implement the jack interface (with start, stop, listen, turnDown, turnUp methods). Each headphone should override this interface to inherit the functionality that the speaker provides and implement accordingly.
Abstract classes, on the other hand, may include methods with an implementation. That's the basic difference and in that sense it may utilize reusing more than an interface. Moreover, they may contain private, protected & non-static fields which you can't via interfaces. You may force subclasses to implement some must-have functionalities with abstract methods (those without implementations). Abstract classes more agile than interfaces.
Of course not to mention, you may only extend one class in java in where you may implement number of interfaces.
Abstract classes vs regular classes
So why not to use regular classes then. What's the benefit of using abstract class? This is pretty simple. If you use abstract classes, you force the core functionality to be implemented by the children. As a developer, you don't need to remember that you should implement the essential functions. This is where abstract classes imposing design constraints over regular classes. Plus by making the class abstract you avoid that (incomplete) class to be created accidentally.