Speak.Me Учить иностранные слова

C#: интерфейсы (Interfaces)

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

  • Все члены интерфейса являются абстрактными. Причем таковыми они являются по умолчанию, т.е. использовать ключевое слово abstract не нужно.
  • Класс (или структура) может реализовывать несколько интерфейсов (а вот наследовать класс только один)

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

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

Объект, реализующий интерфейс, может быть приведен к типу интерфейса:

Расширение интерфейса

Интерфейс может происходить (наследоваться) из другого интерфейса.

Явная реализация интерфейса

Реализация нескольких интерфейсов может привести к конфликту между именами членов. Такой конфликт может быть разрешен с помощью явной реализации члена интерфейса:

Поскольку оба реализуемых интерфейса имеют одинаковые имена членов, класс Widget явно реализует метод Foo интерфейса I2. Это позволяет двум методам сосуществовать в одном классе.

Явная реализация также позволяет скрывать члены класса от доступа из вне класса. При явной реализации нельзя использовать модификаторы доступа, а явно реализованные члены всегда частные (private). Единственные способ вызвать явно реализованный интерфейс — привести экземпляр к типу интерфейса:

Виртуальная реализация членов интерфейса

Неявно реализованный член интерфейса по умолчанию является запечатанным (sealed), т.е. не может быть переопределен в производных классах. Однако, реализуя такой член в базовом классе, его можно пометить как virtual или abstract и тогда его можно будет переопределить в производном классе.

Явно реализованный член интерфейса не может быть помечен как virtual и не может быть переопределен, но может быть перереализован (reimplemented).

Перереализация интерфейса в производном классе

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

В примере класс TextBox явно реализует метод интерфейса IUndo.Undo, в силу чего этот метод не может быть помечен как virtual. Чтобы переопределить его класс RichTextBox должен перереализовать метод интерфейса.