An interface is a group of public members that defines a contract. It is a group of related functions that can belong to a class or struct. In order to fulfil the contract you must supply implementations for all of the interface members. The compiler will enforce the implementation.
An abstract class can contain members with different access modifiers. Interfaces contain only public members and only properties, methods, events and indexers. Constructors and destructors are specific to a particular class, they don’t belong in a general contract.
Abstract class biggest strength is that it can contain implementation code that is shared among all of child classes but its biggest disadvantage is that it can inherit only one base class.
Interface biggest strength is that you can use any number of interfaces but there is no shared code implementation, it contains only definitions.
Updating an interface – Adding or removing members will break implementation or break usage. You can use inheritance to add an interface.
Interface explicit implementation – when two methods have the same name and parameters but the return type is different.
Program to an abstraction (interface) rather than a concrete type (class).
Using interfaces makes the code maintainable, extensible and easily testable. When using an interface you don’t need to care about the implementation details.
The repository pattern – mediates between the domain and data mapping layers using a collection like interfaces for accessing domain objects. It separates the application from the data storage technology.
Interface Segregation Principle – the I in SOLID. Clients should not depend upon methods that they do not use. Interfaces belong to clients, not hierarchies. Granular interfaces that include only the members that a particular function needs.
Example: the class List<T>. It implements Ienumerable<T> for iterating over a collection, data bind to a list control,use linq, ICollection<T> for adding and removing items in the collection, counting and clearing it, IList<T> for more control.
Dependency injection – the goal is to create loosely coupled code by making something else responsible for dependent objects. Patterns: Constructor Injection, Property Injection, Method Injection, Service Locator. Use a Dependency Injection Container.
Mocking – Provide behaviour for the methods we plan to use. Use a Mockup Framework.