Member Procedures
 
具有完全访问TypeClass成员的程序。

声明和定义
声明和定义成员程序。
用法
调用成员程序。
隐藏的参数,这个
隐式访问调用非静态成员过程的实例。
访问权
在会员程序中提及其他成员。
超载
声明两个或多个具有相同名称的成员过程。
静态成员程序
与非静态成员程序的区别。

术语“成员过程”指静态成员和非静态成员程序,除非另有说明。

声明和定义

成员程序的声明与普通模块级别的程序非常相似,只不过它们在TypeClass定义[1]之内被声明,并被定义在外部。

定义成员过程时,过程名称前面加上TypeClass和成员访问运算符(操作符 . (成员访问))的名称。在TypeClass定义中定义一个没有匹配声明的成员过程是一个错误。

以下示例声明并定义了SubFunction成员过程:

'' 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]的名称。

以下示例使用上一个示例中的代码调用SubFunction成员过程:

'' ... foo with non-static members as before ...
#include once "foo1.bi"

Dim bar As foo
bar.f(bar.g())



隐藏的参数,这个

成员程序实际上具有比他们用[3]声明的附加参数。调用它们时,使用实例的名称和操作符 . (成员访问),对该实例的引用与调用中的任何其他参数一起传递,从而允许成员程序直接访问该实例。

由编译器添加的附加参数称为This,由于它是一个引用,所以对This的任何修改实际上都是在被调用时传递给成员过程的实例的修改。您可以像任何其他变量一样使用This,即将其传递给使用相同类型的对象的过程,使用操作符 . (成员访问)等调用其他成员过程并访问成员数据。

然而,大多数情况下,明确使用This是不必要的;成员程序可以引用他们直接通过名称传递的实例的其他成员,而不必使用This操作符 . (成员访问)进行限定。当您需要使用This限定成员名称的唯一时间是成员名称被隐藏时,例如,由参数或局部变量。在这些情况下,限定成员名称是引用这些隐藏成员名称的唯一方法。

Note:
To access duplicated symbols defined outside the Type use:
.SomeSymbol (or ..SomeSymbol if inside a With..End With block).

以下示例使用This关键字来引用名称被参数和局部变量隐藏的成员数据:

Type foo
    Declare Sub f (i As Integer)
    Declare Sub g ()

    i As Integer = 420
End Type

Sub foo.f (i As Integer)
    '' A parameter hides T.i, so it needs to be qualified to be used:
    Print this.i
End Sub

Sub foo.g ()
    '' A local variable hides T.i, so it needs to be qualified to be used:
    Dim i As Integer
    Print this.i
End Sub


访问权

与正常的模块级程序不同,成员程序对于TypeClass的成员有完全访问权限;他们可以参考TypeClass的公共,受保护和私人成员。

超载

成员过程可以被声明为具有与另一个成员过程相同的名称,前提是参数不同,无论是数量还是类型。这被称为重载。

只有参数用于确定过程声明是否是有效的重载。例如,TypeClass可以具有相同名称的静态和非静态成员过程,或具有相同名称的SubFunction成员过程

与声明中需要指定Overload子句的模块级过程不同,成员过程默认是可重载的,不需要Overload子句。

Type T
    Declare Sub f
    
    '' Different number of parameters:
    Declare Sub f (As Integer)
    
    '' Different type of parameters:
    Declare Sub f (ByRef As String)
    
    '' Again, parameters are different:
    Declare Function f (As UByte) As Integer
    
    '' following three members would cause an error,
    '' number of parameters and/or types do not differ:

    '' 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关键字声明,否则将发生编译器错误。像非静态成员过程一样,在类型定义中定义一个没有匹配声明的静态成员过程是一个错误。

不要将此与将它们的变量和对象指定静态存储的过程定义相混淆,只需将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的名称和成员访问运算符(操作符 . (成员访问))的名称进行限定。换句话说,为了调用静态成员程序,不需要一个实例。

以下示例使用上一个示例中的代码,使用两种方式调用静态成员过程:

'' ... foo with static members as before ...
#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)
    '' Ok, self is an instance of foo:
    Print self.i

    '' would cause error
    '' cannot access non-static members, no foo instance:
    '' Print i
End Sub


[1] 将来,成员程序可以在类型或类定义中定义。
[2] 静态成员程序不需要调用对象实例。
[3] 静态成员程序没有由编译器添加这个额外的参数,因此无法访问被调用的对象实例。