Процедуры с полным доступом к элементам
Type or
Class.
Декларация и объявление
Объявление и определение процедур-элементов.
Использование
Вызов процедур-элементов.
Скрытый параметр This
Неявный доступ к экземпляру, с которым нестатические процедуры-элементы
вызываются.
Права доступа
Ссылки на другие элементы в процедурах-элементах.
Перегрузка
Объявление двух или более процедур-элементов с этим именем.
Статические процедуры-элементы
Отличия от нестатических процедур-элементов.
Термин «процедура-элемент» относится к статическим и нестатическим
процедурам-элементам, если не указано иное.
Декларация и объявление
Процедуры-элементы объявляются так же, как обычные процедуры уровня модуля ,
за исключением исключением того, что они были декларируются в
Type
или
Class, а определяются вне его
[1].
При определении процедуры-элемента, имя процедуры должно быть с префиксом
имени
Type или
Class
и оператором доступа (
Оператор . (доступ
к элементу)). Будет ошибкой определение процедуры-элемента без
соответствующей декларации в
Type или
Class.
В следующем примере декларируются и определяются процедуры-элементы
Sub
и
Function:
'' foo1.bi
Type foo
Declare Sub f (As Integer)
Declare Function g As Integer
i As Integer
End Type
Sub foo.f (n As Integer)
Print n
End Sub
Function foo.g As Integer
Return 420
End Function
Использование
Процедуры-элементы вызываются так же, как элементы данных, то есть, их имя
начинается с названия экземпляра объекта и оператора доступа(
Оператор . (доступ
к элементу))
[2].
В следующем примере, используя код из прошлого примера, вызываются
процедуры-элементы
Sub и
Function:
'' ... Foo с не-статическими элементами ...
#include once "foo1.bi"
Dim bar As foo
bar.f(bar.g())
Скрытый параметр This
Процедуры-элементы на самом деле имеют дополнительный параметр, в отличии от
объявленного с
[3].
Когда они вызываются, используя имя экземпляра и
оператора . (доступ к элементу),
ссылка на этот экземпляр передается вместе с другими аргументами при вызове,
позволяя процедуре-элементу иметь прямой доступ к экземпляру.
Дополнительный параметр, называемый
This добавляется
компилятором, и так как он является ссылкой, любые изменения с
This
изменяют экземпляр, который был передан процедуре-элементу, когда она
вызывалась. Вы можете использовать
This
так же, как и любую другую переменную, т.е., передать его в процедуры,
принимающие объект того же типа, вызывать другие процедуры-элементы и
получить доступ к элементам данных с помощью
оператора . (доступ к элементу),
и др.
В большинстве случаев нет необходимости использовать
This , потому что процедуры-элементы и так имеют прямой доступ к элементам данных
своего объекта
с помощью
оператора . (доступ к элементу). Единственно необходимый случай использования
This
, это когда доступ к данным объекта скрыт локальной переменной или
параметром процедуры-элемента (то есть имя локальной переменной или
параметра имеет такое же имя , как и у элемента данных объекта)
Примечание:
Чтобы получить доступ к дублированным символам, определенным вне
TYPE используйте: .SomeSymbol (или ..SomeSymbol
если внутри блока With..End With).
В следующем примере используется ключевое слово
This
для обращения к данным элемента, имя которого скрыто параметром и локальной
переменной:
Type foo
Declare Sub f (i As Integer)
Declare Sub g ()
i As Integer = 420
End Type
Sub foo.f (i As Integer)
'' элемент T.i скрыт параметром,
поэтому для доступа к элементу нужно использовать THIS:
Print this.i
End Sub
Sub foo.g ()
'' элемент T.i скрыт
локальной переменной, поэтому для доступа к элементу нужно использовать
THIS:
Dim i As Integer
Print this.i
End Sub
Права доступа
В отличие от обычных процедур уровня модуля процедуры-элементы имеют права
полного доступа к элементам
Type или
Class,
в котором продекларированы; это относиться к public, protected и private
элементам
Type или
Class.
Перегрузка
Процедуры-элементы могут быть объявлены с тем же именем, как другая
процедура-элемент, если параметры отличаются количеством или типом. Это
называется перегрузкой.
Только параметры используются для определения, является ли данная процедура
допустимой для перегрузки. Например,
Type
или
Class может иметь статические и
не статические процедуры-элементы с одним именем, или процедуры-элементы
Sub
и
Function с таким же именем, но в
примере ниже вы увидите, что только различие параметров в действительности
разрешают перегрузку.
В отличие от процедур уровня модуля, которые должны определять перегрузку с
помощью ключевого слова
Overload ,
процедуры-элементы перегружены по умолчанию и не нуждаются в указании с
помощью
Overload.
Type T
Declare Sub f
'' Другое кол-во параметров:
Declare Sub f (As Integer)
'' Другой тип параметров:
Declare Sub f (ByRef As String)
'' Снова тип
параметра отличается:
Declare Function f (As UByte) As Integer
'' следующие три элемента вызовут
ошибку,
'' потому что
кол-во и тип параметров не отличается:
'' Declare Function f As Integer
'' Declare Function f (As UByte) As String
'' Declare Static Function f (As UByte) As Integer
'' ...
somedata As Any Ptr
End Type
Статические
процедуры-элементы
Статические процедуры-элементы декларируются и объявляются так же, как
нестатические процедуры-элементы, но с ключевым словом
Static
перед декларацией и объявлением.
Процедуры-элементы, объявленные с помощью ключевого слова
Static
, должны быть продекларированы тоже с ключевым словом
Static
в определении
Type или
Class,
или возникнет ошибка компилятора.
Не путайте это с определениями процедур, которые определяют статическую
память для своих переменных и объектов путем добавления ключевого слова
Static
в заголовке процедуры. Ключевое слово
Static
можно использовать в обоих контекстах, однако; статические
процедуры-элементы могут быть определены со статической памятью для
переменной и объекта.
В следующем примере объявляется две статических процедуры-элементы,
первая из которых имеет статическое хранилище для переменной и объекта.
Обратите внимание, что ключевое слово
Static
является необязательным в определении процедуры-элемента:
'' foo2.bi
Type foo
Declare Static Sub f (As Integer)
Declare Static Function g As Integer
i As Integer
End Type
Static Sub foo.f (n As Integer) Static
Print n
End Sub
Function foo.g As Integer
Return 420
End Function
Статические процедуры-элементы могут быть вызваны так же, как
нестатические процедуры-элементы, используя имя экземпляра объекта и
через
оператор . (доступ к элементу)
имя процедуры-элемента.
Они также могут вызываться , путем указания имени процедуры с именем
Type
или
Class,
в котором они были продекларированы и конечно для доступа все так же
используется (
Operator . (Member Access)).
Другими словами экземпляр не является обязательным для вызова
статической процедуры-элемента.
В следующем примере, с помощью прошлого кода, используется оба способа
вызова статической процедуры-элемента:
'' ... foo со статическими
процедурами-элементами ...
#include once "foo2.bi"
Dim bar As foo
bar.f(foo.g())
В
отличие от нестатических процедур-элементов, которые объявляются с
дополнительным параметром
This,
статические процедуры-элементы не передают его в экземпляр при вызове.
Из-за этого статические процедуры-элементы могут ссылаться только на
константы, перечисления, другие статические элементы (данные или
процедуры), и т.д., без указания их имен. Статические процедуры-элементы по-прежнему могут обращаться к
нестатическим элементам при указании экземпляра, например: при помощи параметра или
локальной переменной.
В следующем примере показано как ссылаться к нестатическому элементу из
статического процедуры-элемента:
Type foo
Declare Static Sub f (ByRef As foo)
i As Integer
End Type
Sub foo.f (ByRef self As foo)
'' ОК, сам является экземпляром класса
foo:
Print self.i
'' приведет к ошибке ниже запись:
Print i
'' не удается получить доступ к
нестатическим элементам, нет экземпляра foo:
'' Print i
End Sub
[1]
В будущем процедуры-элементы могут
быть определены в пределах определения
Type или Class.
[2]
Статические процедуры-элементы не
требуют экземпляр объекта для того, чтобы вызываться.
[3]
Статические процедуры-элементы не имеют
дополнительный параметр THIS, добавляемый
компилятором и поэтому не могут получить доступ на экземпляр объекта, из
которого они были вызваны.