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

Синтаксис

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

$ InterfaceDeclaration = INTERFACE ident [“:” BaseInterface]

InterfaceMemberList

END INTERFACE ident ";"

 

$ BaseInterface = qualident

$ InterfaceMemberList = [ InterfaceMemberHeading { “;” InterfaceMemberHeading} ]

$ InterfaceMemberHeading = ProcedureHeading | FunctionHeading | PropertyHeading

$ PropertyHeading = PropertyHeading_Old | PropertyHeading_New

 

$ ProcedureHeading = SUB ident “(“ [FormalParameters] “)”

 

$ FunctionHeading = FUNCTION ident “(“ [FormalParameters] “)” “:”qualident

 

$ PropertyHeading_Old = PROPERTY ident [ Indexes ] ":" ClassType Specifiers [ DEFAULT ";"]

$ Indexes = "(" [ISection {";" ISection}] ")"

$ ISection = ident ":" ClassType

$ Specifiers = ( GET ident | SET ident | GET ident SET ident ) ";"

 

$ PropertyDeclaration_New = PROPERTY ident [ Indexes ] ":" ClassType Specifiers_1 END PROPERTY ident ";" [ DEFAULT ";"]

 

$ Specifiers_1 = ( GetDeclaration | SetDeclaration | GetDeclaration SetDeclaration) ";"

$ GetDeclaration = GET

$ SetDeclaration = SET

Описание

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

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

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

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

Примечание. Наследование от системных интерфейсов запрещено.

В теле интерфейса доступно описание свойств, процедур и функций. В интерфейсе не содержится код реализации или ключевые слова, связанные с кодом реализации, такие как End Sub или End Function. Для объявления свойств доступны как старый, так и новый способ объявления.

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

Для обращения к методам объекта, реализующего интерфейс, по указателю на интерфейс используется следующий синтаксис:

<имя объекта>.<имя метода>.

Пример

Рассмотрим пример создания пользовательской коллекции символьных элементов. Для описания структуры коллекции используется пользовательский интерфейс IMyInterface. В данном интерфейсе описана сигнатура двух свойств: Item и Items. Свойство Item доступно на чтение и запись, и объявлено свойством по умолчанию (доступ к данному свойству возможен без указания самого свойства, при указании только индекса необходимого элемента).  Для доступа ко всей коллекции используется свойство Items, доступное только для чтения. При описании структуры свойств используется старый (для Item)  и новый (для Items) способ объявления. Реализация данных свойств находится в классе MyArray. Все значения коллекции будут храниться во внутреннем символьном массиве PropValue класса MyArray.

Interface IMyInterface

Sub Set_Item(i: Integer; s: String);

Function Get_Item(i: Integer): String;

Public Property Item(i: Integer): String Get Get_Item Set Set_Item; Default; //Свойство по умолчанию

 

Public Property Items: Array Of String

Get

End Property Items;

End Interface IMyInterface;

 

Class MyArray: Object, IMyInterface

 

Private PropValue: Array Of String;

 

Public Constructor Create(Length: Integer);

Begin

PropValue := New String[Length];

End Constructor Create;

 

Sub Set_Item(i: Integer; s: String);

Begin

PropValue[i] := s;

End Sub Set_Item;

 

Function Get_Item(i: Integer): String;

Begin

Return PropValue[i];

End Function Get_Item;

Public Property Item(i: Integer): String Get Get_Item Set Set_Item; Default; //Свойство по умолчанию

 

Public Property Items: Array Of String

Get

Begin

Return PropValue;

End Get

End Property Items;

End Class MyArray;

 

Sub Main;

Var

Arr: IMyInterface;

s: String;

Begin

Arr := New MyArray.Create(2);

Arr(0) := "Первый элемент";

Arr.Item(1) := "Второй элемент";

For Each s In Arr.Items Do

Debug.WriteLine(s);

End For;

End Sub Main;

После запуска процедуры Main будет создан экземпляр пользовательской коллекций. Размер коллекции - два элемента. Так как свойство Item установлено свойством по умолчанию, то установка его значений возможна без указания наименования самого свойства. Значения элементов будут установлены различными способами. Для проверки установленные значения элементов коллекции будут выведены в консоль среды разработки.

См. также:

Описания и синтаксические правила