Доброго времени суток уважаемые кодеры и не только. Сегодня я решил написать небольшую статейку, в которой пойдёт речь о интерфейсах и абстрактных классах в языке C#. Тем из вас, кто имеет хоть немного опыта в C#, уже вероятно известно о существовании таких понятий как abstract class и Interface, и что оба могут быть реализованы или унаследованы другими классами. Вы возможно так-же задавались вопросом "что и в каких случаях использовать?". Что-ж, давайте для начала рассмотрим, в чём состоят основные отличия данных классов. Interface - все члены должны быть реализованы. - содержит только открытые члены. - один класс может реализовывать несколько интерфейсов. - не изменяем. Т.е. при изменении интерфейса придётся изменять весь, от него зависящий, код. - описывает поведение "has-a"(содержит). abstract class - может сам содержать реализацию. - возможна принудительная реализация для дочернего класса с помощью модификатора abstract. - возможна опциональная реализация для дочернего класса с помощью модификатора virtual. - не поддерживает множественного наследования. - может быть изменён, хотя и с некоторыми ограничениями. - описывает поведение "is-a"(является). Так что-же и когда использовать? Представим себе, что мы программируем движок варез-портала. Один из наших классов называется Content от которого наследуют классы Post, Comment, Download. Должен ли наш базовый класс Content быть абстрактным? Так как мы в нашем движке класс Content не используем, то есть никогда не создаём объект данного типа (это было бы бессмысленно, ведь понятие Content не выражает никакого конкретного смысла в отличии от Post, Comment и Download) следует сделать его абстрактным. В таком случае наш базовый класс используется для полиморфного поведения дочерних классов. Теперь добавим нашему классу Content немного функционала и определим в нём метод Edit(). Если этот метод будет иметь одинаковое поведение для всех дочерних классов, то будет достаточно определить его один раз в базовом классе. В данном случае разумно сделать класс Content абстрактным с уже реализованным методом Edit(). Если поведение метода для дочерних классов будет различным, то следует использовать интерфейс. В итоге можно отметить, что в большинстве случаев стоит отдать предпочтение абстрактным классам. Для принятия решения в каком случае какой тип более подходящий, можно воспользоваться такой цепочкой решений: Имея базовый класс для группы схожих классов нас интересуют тответы на вопросы: Используется ли сам класс как логическая единица? То есть инстанцируем ли мы его. Если да: используем обыкновенный класс. Если нет: используем абстрактный класс. Существуют ли различия в поведении членов данной группы? Или имеют общий вид в нескольких группах и будут использоваться полиморфно. Если да: используем интерфейс. Источники: msdn.microsoft.com seregaborzov.wordpress.com aspnetzone.de csharp-online.net