- a class may inherit from only one other class, but can implement many interfaces
- an interface may not have any fields, expect defining constants, while an abstract class can
- an abstract class may define a constructor, while an interface can not
Default methods are restricted to input parameters and method calls. They are stateless in nature. An abstract class may have state. Hence, from the perspective of design, I would suggest to use abstract classes whenever you need code reuse. Reducing code reuse to package scope is a good design principle in my opinion.
Interfaces are perfect to model and communicate the concepts of a package, a library, a domain or an application. They do not rely on implementation details and allow to replace the implementations at will. They support testing and modularization.