Определение интерфейсов

В предыдущих постах я писал о том, на что похожи объявления интерфейсов С#. Они выглядят подобно объявлениям классов, где ключевое слово class заменено interface, а методы не имеют тела. Однако обратите внимание еще на ряд важных моментов. Если вы следуете рекомендованным соглашениям, то имена интерфейсов должны начинаться с буквы I.

Таким образом, интерфейсные типы очень легко обнаружить в коде. Интерфейсы могут иметь присоединенные к ним модификаторы доступа. Они указывают на то, видимо ли объявление интерфейса вне сборки. Поскольку большинство интерфейсов представляют собой контракты взаимодействия между поставщиками и потребителями, интерфейсы обычно объявляются как public.

Члены интерфейса не могут иметь никаких модификаторов доступа. Однако они могут быть декорированы модификатором new, о котором речь пойдет ниже. Члены интерфейсов всегда неявно общедоступны (public). Какой может быть смысл в не общедоступных членах интерфейса, если назначение интерфейса состоит в том, чтобы позволить двум объектам взаимодействовать друг с другом?

Интерфейсы определяют контракты

Чтобы подчеркнуть, что интерфейс только специфицирует контракт, следует привести аналогию между объявлением интерфейса и языками IDL (Interface Description Language — язык описания интерфейсов) и WSDL (Web Services Description Language — язык описания веб-служб). И СОМ, и CORBA используют IDL для определения интерфейсов.

Его синтаксис подобен С++. Обычно IDL передается через транслятор, такой как midl. ехе для СОМ, чтобы генерировать оболочки и, возможно, прокси и заглушки для любого необходимого языка.

Другим примером может служить WSDL, который является гораздо более выразительным, чем IDL. Схема XML определяет формат WSDL, а документ WSDL применяется для описания контракта, или интерфейса, сетевой службы. Порядок использования подобен IDL. Документ WSDL прогоняется через транслятор для любого языка, на котором осуществляется реализация или потребление службы.

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

На практике обычно имеет смысл помещать объявления интерфейсов в отдельную сборку, содержащую только определения интерфейсов и константы, чтобы потребитель и поставщик могли основывать свои реализации в точности на одной и той же версии интерфейса. Замечательным примером этого может служить библиотека Managed Addln Framework (MAF), которая появилась в .NET 3.5.

Что может быть интерфейсом?

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

Когда речь идет об интерфейсах, то предпочтительнее считать, что если интерфейс В наследуется от интерфейса А, это значит, что если реализован интерфейс В, то также должен быть реализован и интерфейс А. Наследование классов просто подразумевает отношение “является” (is-a), где базовая реализация также наследуется.

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

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

Ниже приведен пример объявления интерфейса:

1
2
3
4
5
6
7
8
public delegate void DBEvent ( IMyDatabase sender );
public interface IMyDatabase : ISerializable, IDisposable
{
void Insert ( object element );
int Count { get; }
object this[ int index ]  { get; set; }
event DBEvent dbChanged;
}

В данном примере IMyDatabase также реализует ISerializable и IDisposable. Поэтому любой конкретный тип, реализующий IMyDatabase, также должен реализовать ISerializable и IDisposable; в противном случае этот конкретный тип не ском-пилируется.

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

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100