Abstract (Base) classes give you semi-concrete classes to implement your class hierarchy against. They allow you to do several things:
- Consolidate common behavior (unlike an interface which only defines the contract)
- Provide default (and optionally override-able) implementations for functions
- Provide well defined branch points for inheritance hierarchies
- Control IoC injection points
The list goes on.