Short answer
Use an interface to define a capability or contract that unrelated types can implement, especially since you can supply default methods and a type can implement many interfaces.
Explanation
Use an abstract class when you need shared mutable state, constructors, or non-public members across a closely related family, since a class can extend only one. With default methods the gap narrowed, but interfaces still can't hold instance state, so 'shared state and partial implementation' remains the deciding factor for abstract classes.
Common mistakes
- Choosing an abstract class just to share code when an interface with default methods is enough.
- Forgetting that interfaces cannot hold instance state.