Выбор между классами и интерфейсами

Обновлен: Ноябрь 2007

Интерфейс определяет подписи для набора членов, предоставляемых разработчиками. Интерфейсы не могут предоставить членам подробные сведения о реализации. Например, в интерфейсе ICollection определяются члены, относящиеся к работе с коллекциями. Каждый класс, реализующий интерфейс, должен предоставить этим членам подробные сведения о реализации. Классы способны реализовывать несколько интерфейсов.

Классы определяют как подписи членов, так и подробные сведения о реализации для каждого члена. Классы Abstract (MustInherit в Visual Basic) могут вести себя, как интерфейсы или обычные классы, в которых они могут определять члены; также они могут предоставлять подробные сведения о реализации, но это не является обязательным. Если абстрактный класс не предоставляет подробные сведения о реализации, для этого требуются конкретные классы, являющиеся производными от абстрактного класса.

И абстрактные классы, и интерфейсы поддерживают отделение контракта от реализации, однако интерфейсы не могут описывать новые члены в более поздних версиях, тогда как абстрактные классы могут добавлять члены по мере необходимости для поддержания дополнительной функциональности.

Предпочтительнее определение классов, а не интерфейсов.

В более поздних версиях библиотеки можно безопасно добавлять в классы новые члены; добавить члены в интерфейсы невозможно, не нарушая существующего кода.

Используйте абстрактные ("MustInherit" в Visual Basic) классы вместо интерфейсов для отделения контракта от реализаций.

Определяйте интерфейс для предоставления полиморфной иерархии типов значений.

Типы значений должны наследовать от класса ValueType и могут наследовать только от класса ValueType, поэтому они не могут использовать классы для отделения контракта от реализации. В этом случае, если для типов значений требуется полиморфное поведение, следует использовать интерфейс.

Рекомендуется определять интерфейсы для достижения результата, подобного множественному наследованию.

Если тип должен реализовать несколько контрактов или контракт применим к большому числу типов, используйте интерфейс. Например, интерфейс IDisposable реализуется типами, используемыми в различных сценариях. Требование, чтобы классы, производные от базового, можно было освободить, лишает иерархию классов гибкости. Такие классы, как MemoryStream, которые должны наследовать свои основанные на потоках контракты от родительских классов, не смогут этого сделать и также будут освобождаться.

Фрагменты — © Корпорация Майкрософт (Microsoft Corp.), 2005. Все права защищены.

Фрагменты — © Addison-Wesley Corporation. Все права защищены.

Дополнительные сведения о рекомендациях по разработке см. в книге "Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries", Krzysztof Cwalina and Brad Abrams, Addison-Wesley, 2005.

См. также

Основные понятия

Выбор между классами и структурами

Другие ресурсы

Правила разработки типов

Руководство по разработке библиотек классов