Abstract classes are often used in frameworks to give you a partial implementation. They provide fully functional code in some methods, but leave other methods empty for you to override in a derived class. Or they might provide a very basic implementation of every method with the invitation to override any that you'd like to make more interesting. Swing has some in that style - like a default mouse event listener that implements every method to do nothing. You can extend it and override only the methods you really care about. The other thing is the "abstract" bit, which means nobody can ever do a new() to create an instance of the class. That's nice when it is a partial implementation, because it's not complete enough for anyone to use. When you get into some rather advanced situations it may be valuable to follow a rule "never extend a concrete class". In those cases it's good to give other programmers an abstract class that they may extend.
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
They are especially helpful when you are in a team environment and you are responsible for modeling some aspect of the program which other developers may use. By laying the foundation, so to speak, with an abstract class, you define how you're model is to be used. For instance, I've recently worked on a project where we had 3 types of users -- regular employees, supervisors, and reviewers. We made an abstract class Employee, which served as a superclass to each type of user. Now, in order to extend the Employee class, developers needed to override several key database methods (which were particular to a given type of user). The abstract Employee class let the other developers know what exactly they needed to implement in the subclasses.