Предполагая, что вы имеете в виду интерфейсы в объектно-ориентированных языках со статической типизацией, основное использование заключается в утверждении, что ваш класс следует определенному контракту или протоколу.
Скажем, у вас есть:
public interface ICommand
{
void Execute();
}
public class PrintSomething : ICommand
{
OutputStream Stream { get; set; }
String Content {get; set;}
void Execute()
{
Stream.Write(content);
}
}
Теперь у вас есть подстановочная структура команд. Любой экземпляр класса, который реализует IExecute, может быть сохранен в некотором списке, скажем, что-то, что реализует IEnumerable, и вы можете проходить через него и выполнять каждый, зная, что каждый объект будет просто делать правильные вещи. Вы можете создать составную команду, реализовав CompositeCommand, который будет иметь собственный список команд для выполнения, или LoopingCommand для многократного запуска набора команд, тогда у вас будет большая часть простого интерпретатора.
Когда вы можете свести набор объектов к общему поведению, у вас может быть причина извлечь интерфейс. Кроме того, иногда вы можете использовать интерфейсы, чтобы предотвратить случайное вторжение объектов в проблемы этого класса; например, вы можете реализовать интерфейс, который позволяет клиентам только получать, а не изменять данные в вашем объекте, а большинство объектов получают только ссылку на интерфейс поиска.
Интерфейсы работают лучше всего, когда ваши интерфейсы относительно просты и делают несколько предположений.
Посмотрите на принцип подстановки Лискова, чтобы разобраться в этом.
Некоторые статически типизированные языки, такие как C ++, не поддерживают интерфейсы как первоклассную концепцию, поэтому вы создаете интерфейсы с использованием чисто абстрактных классов.
Обновление
Поскольку вы, похоже, спрашиваете об абстрактных классах и интерфейсах, вот мое предпочтительное упрощение:
- Интерфейсы определяют возможности и функции.
- Абстрактные классы определяют основные функции.
Как правило, я делаю рефакторинг интерфейса извлечения перед созданием абстрактного класса. Я с большей вероятностью создаю абстрактный класс, если считаю, что должен быть заключен творческий контракт (в частности, что подклассы всегда должны поддерживать определенный тип конструктора). Однако я редко использую «чистые» абстрактные классы в C # / Java. У меня гораздо больше шансов реализовать класс хотя бы с одним методом, содержащим осмысленное поведение, и использовать абстрактные методы для поддержки шаблонных методов, вызываемых этим методом. Тогда абстрактный класс является базовой реализацией поведения, которым могут пользоваться все конкретные подклассы без необходимости переопределения.