One point missing from the answers here is the idea of who will be implementing the interface.
If your component wants to return instances of abstract types to its callers, where the concrete types are defined internally and hidden from callers, use an interface. Conversely, if your component consumes or accepts instances of abstract types that its callers must implement, abstract classes are usually a better choice.
Anticipating evolution and maintaining binary compatibility tips the scales here. With an abstract class, you can add methods and, if you provide a base implementation, existing implementations of the abstract class will continue to work fine. With an interface, adding a method breaks binary compatibility, for no existing implementation could possibly continue to compile properly without changing to define the new method.
The Apache Cactus project has a good discussion on how to resolve these obligations.