Что такое интерфейс класса

Что такое интерфейс класса

Описание ООП-интерфейса, если отвлечься от деталей синтаксиса конкретных языков, состоит из двух частей:

  • Имя интерфейса, которое строится по тем же правилам, что и другие идентификаторы используемого языка программирования. Разные языки и среды разработки имеют различные соглашения по оформлению кода, в соответствии с которыми имена интерфейсов могут формироваться по некоторым правилам, облегчающим отличение имени интерфейса от имён других элементов программы. Например, в технологии COM и всех поддерживающих её языках действует соглашение, согласно которому имя интерфейса строится по шаблону «I », то есть состоит из написанного с заглавной буквы осмысленного имени, которому предшествует прописная латинская буква I (IUnknown, IDispatch, IStringList и так далее).
  • Методы интерфейса. В описании интерфейса определяются имена и сигнатуры входящих в него методов, то есть процедур или функций класса.

Использование интерфейсов возможно двумя способами:

  • Класс может реализовывать интерфейс. Реализация интерфейса заключается в том, что в описании класса данный интерфейс указывается как реализуемый, а в коде класса обязательно определяются все методы, которые описаны в интерфейсе, в полном соответствии с сигнатурами из описания этого интерфейса. То есть, если класс реализует интерфейс, для любого экземпляра этого класса существуют и могут быть вызваны все описанные в интерфейсе методы. Один класс может реализовать несколько интерфейсов одновременно.
  • Возможно объявление переменных и параметров методов как имеющих тип-интерфейс. В такую переменную или параметр может быть записан экземпляр любого класса, реализующего интерфейс. Если интерфейс объявлен как тип возвращаемого значения функции, это означает, что функция возвращает объект класса, реализующего данный интерфейс.

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

Таким образом, с одной стороны, интерфейс — это контракт, который обязуется выполнить класс, реализующий его, с другой стороны, интерфейс — это тип данных, потому что его описание достаточно четко определяет свойства объектов, чтобы наравне с классом типизировать переменные. Следует, однако, подчеркнуть, что интерфейс не является полноценным типом данных, так как он задаёт только внешнее поведение объектов. Внутреннюю структуру и реализацию заданного интерфейсом поведения обеспечивает класс, реализующий интерфейс; именно поэтому «экземпляров интерфейса» в чистом виде не бывает, и любая переменная типа «интерфейс» содержит экземпляры конкретных классов.

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

Например, интерфейс «Cloneable» может описать абстракцию клонирования (создания точных копий) объектов, специфицировав метод «Clone», который должен выполнять копирование содержимого объекта в другой объект того же типа. Тогда любой класс, объекты которого может понадобиться копировать, должен реализовать интерфейс Cloneable и предоставить метод Clone, а в любом месте программы, где требуется клонирование объектов, для этой цели у объекта вызывается метод Clone. Причем использующему этот метод коду достаточно иметь только описание интерфейса, он может ничего не знать о фактическом классе, объекты которого копируются. Таким образом, интерфейсы позволяют разбить программную систему на модули без взаимной зависимости кода.

Интерфейсы и абстрактные классы

Можно заметить, что интерфейс, фактически — это просто чистый абстрактный класс, то есть класс, в котором не определено ничего, кроме абстрактных методов. Если язык программирования поддерживает множественное наследование и абстрактные методы (как, например, C++), то необходимости во введении отдельного понятия «интерфейс» не возникает. Аналогичные сущности описываются в виде абстрактных классов и наследуются классами для реализации абстрактных методов.

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

Множественное наследование и реализация интерфейсов

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

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

  • Запрет. В одном классе просто запрещается реализовывать несколько интерфейсов, имеющих методы с одинаковыми сигнатурами. Если для какого-то класса требуется комбинация несовместимых интерфейсов, программист должен выбрать другой путь решения проблемы, например, выделить несколько классов, каждый из которых реализует один из необходимых интерфейсов, и использовать их экземпляры совместно.
  • Явное разрешение неоднозначности. В случае обнаружения компилятором коллизии от программиста требуется явно указать, метод какого из интерфейсов он реализует и вызывает. То есть одноимённые методы реализуются раздельно, а при вызове указывается, какой из них вызывается. Вариантом этого решения является явное переименование для совпадающих по именам наследуемых или реализуемых методов, за счёт чего в пределах реализующего класса нет одноимённых методов, но при обращении через интерфейс всегда вызывается нужная реализация.
  • Общая реализация одноимённых методов. Если наследуется или реализуется несколько методов с одной и той же сигнатурой, то они объединяются в интерфейсе-наследнике, а в классе-реализаторе получают одну общую реализацию. Это хорошо подходит для случаев, когда одноимённые методы разных интерфейсов идентичны по предполагаемой функциональности, но может вызвать нежелательные эффекты, если поведение этих методов должно различаться.
Читайте также:  Сколько времени требуется для зарядки акб

Интерфейсы в конкретных языках и системах

Реализация интерфейсов во многом определяется исходными возможностями языка и целью, с которой интерфейсы введены в него. Очень показательны особенности использования интерфейсов в языках C++, Java и Object Pascal системы Delphi, поскольку они демонстрируют три принципиально разные ситуации:

  • В объектной подсистеме языка Object Pascal никаких интерфейсов не было, их поддержка была введена в Delphi 2 для обеспечения написания и использования COM-компонентов. Соответственно, механизм интерфейсов Delphi ориентирован, в первую очередь, на использование технологии COM.
  • В Java интерфейсы изначально входят в язык, являясь неотъемлемой его частью.
  • В C++ интерфейсов, строго говоря, нет вообще. Механизм, аналогичный интерфейсам (и, исторически предшествующий им) реализуется другими средствами чрезвычайно мощной объектной подсистемы этого языка.

Delphi

В COM технологии фирмы Delphi напоминают классы. Как все классы являются наследниками класса IUnknown , соответствующего стандартному одноимённому COM-интерфейсу.

Пример объявления интерфейса:

Для того, чтобы объявить о реализации интерфейсов, в описании класса необходимо указать их имена в скобках после ключевого слова class , после имени класса-предка. Так как интерфейс — это контракт, который нужно выполнить, программа не компилируется пока в реализующем классе не будет реализована procedure DoSomething;

Вышеупомянутая ориентированность интерфейсов Delphi на технологию COM привела к некоторым неудобствам. Дело в том, что интерфейс IUnknown (от которого наследуются все остальные интерфейсы) уже содержит три метода: QueryInterface,_AddRef, _Release , следовательно, любой класс, реализующий любой интерфейс, обязан реализовать эти методы, даже если интерфейс и класс не имеют никакого отношения к COM.

Пример класса, реализующего интерфейс

Программист должен правильно реализовать методы QueryInterface,_AddRef, _Release . Чтобы избавиться от необходимости писать стандартные методы, предусмотрен библиотечный класс TInterfacedObject — он реализует три вышеупомянутых метода и любой класс, наследуемый от него и его потомков, получает эту реализацию:

Пример класса — наследника TInterfacedObject

Недостатком такого решения является ограничение на структуру дерева классов: невозможно унаследовать класс, реализующий интерфейс, от какого-либо другого своего класса.

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

Пример определения интерфейса:

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

Тестируем все вместе:

В отличие от C++, класс в объекты от интерфейсов в

Объявление интерфейсов

Объявление интерфейсов очень похоже на упрощенное объявление классов.

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

Далее записывается ключевое слово interface и имя интерфейса.

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

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

Читайте также:  Как поставить автоматический ответ в outlook

Затем в фигурных скобках записывается тело интерфейса.

Тело интерфейса состоит из объявления элементов, то есть полей-констант и абстрактных методов. Все поля интерфейса автоматически являются public final static , так что эти модификаторы указывать необязательно и даже нежелательно, чтобы не загромождать код. Поскольку поля являются финальными, необходимо их сразу инициализировать.

Все методы интерфейса являются public abstract и эти модификаторы также необязательны.

Как мы видим, описание интерфейса гораздо проще, чем объявление класса.

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

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

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

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

Интерфейсы в UML

В классы со стереотипом «interface». Либо в виде кружочков, в этом случае содержащиеся в интерфейсе UML-операции не отображаются.

См. также

Ссылки

Wikimedia Foundation . 2010 .

Смотреть что такое "Интерфейс (ООП)" в других словарях:

Интерфейс (вычислительная техника) — Интерфейс (от англ. interface поверхность раздела, перегородка) совокупность средств и методов взаимодействия между элементами системы. В зависимости от контекста, понятие применимо как к отдельному элементу (интерфейс элемента), так и к… … Википедия

Интерфейс (информатика) — Интерфейс (от англ. interface поверхность раздела, перегородка) совокупность средств и методов взаимодействия между элементами системы. В зависимости от контекста, понятие применимо как к отдельному элементу (интерфейс элемента), так и к… … Википедия

Интерфейс (компьютеры) — Интерфейс (от англ. interface поверхность раздела, перегородка) совокупность средств и методов взаимодействия между элементами системы. В зависимости от контекста, понятие применимо как к отдельному элементу (интерфейс элемента), так и к… … Википедия

Интерфейс (программирование) — Интерфейс (от англ. interface поверхность раздела, перегородка) совокупность средств и методов взаимодействия между элементами системы. В зависимости от контекста, понятие применимо как к отдельному элементу (интерфейс элемента), так и к… … Википедия

Интерфейс системный — Интерфейс (от англ. interface поверхность раздела, перегородка) совокупность средств и методов взаимодействия между элементами системы. В зависимости от контекста, понятие применимо как к отдельному элементу (интерфейс элемента), так и к… … Википедия

Интерфейс (объектно-ориентированное программирование) — У этого термина существуют и другие значения, см. Интерфейс (значения). Интерфейс (от лат. inter «между», и face «поверхность») семантическая и синтаксическая конструкция в коде программы, используемая для специфицирования… … Википедия

Класс (ООП) — Класс, наряду с понятием «объект», является важным понятием объектно ориентированного подхода в программировании (хотя существуют и бесклассовые объектно ориентированные языки, например, Прототипное программирование). Под классом подразумевается… … Википедия

Класс (программирование) — У этого термина существуют и другие значения, см. Класс. Класс в программировании набор методов и функций. Другие абстрактные типы данных метаклассы, интерфейсы, структуры, перечисления характеризуются какими то своими, другими… … Википедия

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

ООАП — Объектно ориентированное программирование (ООП) парадигма программирования, в которой основными концепциями являются понятия объектов и классов (либо, в менее известном варианте языков с прототипированием прототипов). Класс это тип, описывающий… … Википедия

Интерфейс класса, не определяемый явно в управляемом коде — это интерфейс, который предоставляет доступ ко всем открытым методам, свойствам, полям и событиям, к которым предоставлен явный доступ в объекте .NET. Этот интерфейс может быть сдвоенным или интерфейсом диспетчеризации. Интерфейс классов получает имя самого класса .NET с символом подчеркивания перед ним. Например, если имя класса — Mammal, интерфейс класса получит имя _Mammal.

В случае с производными классами интерфейс класса также предоставляет доступ ко всем открытым методам, свойствам и полям базового класса. Производный класс также предоставляет доступ к интерфейсу класса для каждого базового класса. Например, если класс Mammal является расширением класса MammalSuperclass, который, в свою очередь, является расширением класса System.Object, объект .NET предоставляет COM-клиентам доступ к трем интерфейсам классов с именами _Mammal, _MammalSuperclass и _Object.

Читайте также:  Поиск групп в вацапе

Например, рассмотрим следующий класс .NET:

COM-клиент может получить указатель на интерфейс класса с именем _Mammal , описанный в библиотеке типов, созданной программой программой экспорта библиотеки типов (Tlbexp.exe) tool generates. Если класс Mammal реализовал один или несколько интерфейсов, они будут отображены в компонентном классе.

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

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

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

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

С помощью атрибута ClassInterfaceAttribute отключите автоматическую генерацию интерфейса класса и реализуйте для класса явный интерфейс, как показано в следующем фрагменте программы:

Значение ClassInterfaceType.None предотвращает создание интерфейса класса при экспорте метаданных класса в библиотеку типов. В предыдущем примере COM-клиенты могут получить доступ к классу LoanApp только с помощью интерфейса IExplicit .

Использование интерфейса класса является допустимым вариантом для клиентов со сценарием, клиентов Microsoft Visual Basic 6.0, а также клиентов с поздним связыванием, которые не кэширует идентификаторы DispId членов интерфейса. Идентификаторы DispId определяют члены интерфейса, разрешающие позднее связывание.

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

Во избежание нарушений в работе COM-клиентов с поздним связыванием при использовании интерфейсов классов необходимо применить атрибут ClassInterfaceAttribute со значением ClassInterfaceType.AutoDispatch. Это значение реализует интерфейс диспетчеризации класса, но пропускает описание интерфейса в библиотеке типов. Без описания интерфейса клиенты не могут кэшировать идентификаторы DispId во время компиляции. Хотя этот тип интерфейса по умолчанию используется для интерфейса класса, это значение атрибута можно задать явным образом.

Чтобы получить идентификатор DispId члена интерфейса во время выполнения, COM-клиенты могут вызывать IDispatch.GetIdsOfNames. Чтобы вызвать метод для интерфейса, следует передать возвращенный идентификатор DispId в качестве аргумента для IDispatch.Invoke.

Сдвоенные интерфейсы позволяют COM-клиентам выполнять раннее и позднее связывание с членами интерфейсов. В режиме разработки и при тестировании может оказаться полезным сделать интерфейс класса сдвоенным. Этот вариант также допустим и для управляемого класса (и его базовых классов), который никогда не будет изменяться. Во всех других случаях следует воздержаться от того, чтобы делать интерфейс класса сдвоенным.

Допустим, что часть методов и полей совпадает по описанию. Это значит, что мы теоретически можем одинаково обращаться с экземплярами и первого и второго классов.

а в движке можно выбирать через что рисовать картинку, OpenGL DirectX и прочее.

в самом движке уже чтобы рисовать конретно через эти отдельные API вот такие классы
class DriverOpenGL : public Driver<
void BeginRender( void )<
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
>
void EndRender( void )<
SwapBuffers( HDc );
>
void SetClearColor( const Color& color )<
glClearColor( color.r, color.g, color.b, color.a );
>
>;

для DirectX нужны свои версии этих функций.

class DriverDirect3D11 : public Driver<
void BeginRender( void )<
d3d11DevCon->ClearRenderTargetView(renderTargetView, bgColor);
d3d11DevCon->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
>
void EndRender( void )<
if (m_vsync_enabled)Present(1, 0);>
elsePresent(0, 0);>>
>
void SetClearColor( const Color& color )<
bgColor = color;
>
>;

а в самой программе, в игре, там будет просто

Device* device = CreateGameDevice( x, 800, 600 );
Driver* driver = device->GetVideoDriver();

while(true)<
driver->BeginRender();
//объекты для рисования
driver->EndRender();
>
return 0;
>

реализуя тот или иной интерфейс класс обязуется предоставить реализацию для членов интерфейса

например, есть интерфейс перемещаемого объекта
интерфейс требует, чтобы у класса были
— два поля для координат
— метод для перемещения

класс наследующий такой интерфейс обязан реализовать у себя
— два поля для координат
— метод для перемещения

Внимание
Ссылка на основную публикацию
Что означает охват в статистике вконтакте
Что такое охват подписчиков во Вконтакте Как посмотреть охват? Для сообщества Перейдите в сообщество, на панели управления нажмите кнопку «Статистика»,...
Что делать если взломали сим карту
Подавляющее большинство современных телефонов оборудовано лотком под сим-карту, вытащить который очень легко с помощью скрепки или иглы. Какие-то телефоны после...
Что делать если забыл название игры
В сообществе Лига Геймеров очень часто всплывают посты "Помогите найти игру". Там их не очень жалуют. Для этого и создано...
Что означает ошибка esp
Однажды ни с того ни с сего во время достаточно спокойной езды загорелась ошибка: "Сервис: ESP", затем следом появилось сообщение...
Adblock detector