Abstract classes are useful when you need to enforce the basic shape and behaviour of a class hierarchy. Once inherited there's no escaping your abstract class. I'd use abstract classes where I wanted to create a fixed set of behaviours for an entire class hierarchy.
Applying extension methods to an interface is useful for applying common behaviour across classes that may share only a common interface. Such classes may already existsexist and be closed to extensions via other means.
For new designs I would favour the use of extension methods on interfaces for the flexible composition. For a hierarchy of Types, extension methods provide a means to extend behaviour without having to open the entire hierarchy for modification. Extension
However, extension methods can implement scenarios that depend only on certain interfaces (roles) that are implemented (played) by a potentially wide varietyunable to access private implementation, so at the top of candidate classes. This is a very flexible way of buildinghierarchy, if I need to encapsulate private implementation behind a domain model; keeping your classes fairly dumb and providing scenarios that play across domain classespublic interface then an abstract class would be the only way.