实例3-3 字段的使用
1.文件列表
本实例由以下文件组成。
该实例实现步骤如下。
2.实现步骤
1 在本章的项目chapter3下,右键单击该项目名下面的文件夹“类及对象”,在弹出菜单中选择“添加”→“类”菜单命令,在弹出的对话框中输入名称FieldClass,单击“添加”按钮完成类的创建。
2 在本章的项目chapter3下,右键单击该项目名下面的文件夹“类及对象”,在弹出菜单中选择“添加”→“模块”菜单命令,在弹出的对话框中输入名称FieldModule,单击“添加”按钮完成模块的创建。
3.代码实现
(1)FieldClass.vb的实现
双击FieldClass.vb文件,在其中添加代码3-7中的代码。
代码3-7 FieldClass.vb
01. Public Class FieldClass 02. Public ReadOnly read As Integer '只读字段 03. Public Const conMax As Integer = 100 '常量 04. Public example As Integer '实例字段 05. '全局静态变量声明用“Shared”,不能用于定义局部静态变量 06. Public Shared sh As Integer = 0 07. Public Sub New(ByVal r As Integer, ByVal e As Integer) '构造函数 08. read = r 09. example = e 10. sh = sh + 1 11. End Sub 12. Public Sub aside(ByVal r As Integer, ByVal e As Integer) 13. ' read = r不能赋值 14. 'conMax = 0 不能赋值 15. example = e 16. sh = sh + 1 17. End Sub 18. End Class
代码3-7执行步骤如下:
① 第2行代码定义了一个只读字段,第3行代码定义了一个常量,第4行代码定义了一个实例字段,第6行代码定义了一个全局静态字段,在这要注意,全局静态字段用关键字Shared声明,但Shared却不能声明局部的静态变量;
② 第7行代码声明该类带参数的构造函数,用于为只读字段、实例字段、全局静态字段赋值;
③ 第8行和第9行代码分别将构造函数的参数值赋给只读和实例字段,第10行代码是将全局静态字段加1;
④ 第12行代码声明一个带参数的Sub函数,功能与构造函数一样;
⑤ 第13行和第14行代码用于为只读字段和常量赋值,但都会出错,因为只读字段只能在字段声明中或构造函数中重新赋值,而常量只能在声明中初始化,以后不能再修改。
(2)FieldModule.vb的实现
双击FieldModule.vb文件,在其中添加代码3-8中的代码。
代码3-8 FieldModule.vb
01. Module FieldModule 02. Private Function els() As Integer 03. '局部静态变量声明用“ Static ”,只能在过程中定义 04. Static st As Integer = 0 05. st = st + 1 06. Return st 07. End Function 08. Sub main() 09. Dim field As New FieldClass(30, 50) '调用构造函数 10. Console.WriteLine(" 只读字段:" & field.read) 11. Console.WriteLine(" 实例字段:" & field.example) 12. Console.WriteLine(" 常量:" & FieldClass.conMax) 13. Console.WriteLine(" 全局静态变量:" & FieldClass.sh) 14. Console.WriteLine(" 局部静态变量:" & els()) 15. field.aside(40, 60) 16. Console.WriteLine(" 只读字段:" & field.read) 17. Console.WriteLine(" 实例字段:" & field.example) 18. Console.WriteLine(" 常量:" & FieldClass.conMax) 19. Console.WriteLine(" 全局静态变量:" & FieldClass.sh) 20. Console.WriteLine(" 局部静态变量:" & els()) 21. End Sub 22. End Module
代码3-8执行步骤如下:
① 第2行到第7行代码声明了一个函数,其中定义一个局部静态变量,将其值加1再返回;
② 第9行代码调用FieldClass类的构造函数,并设置参数,即设置只读、实例、全局静态字段的值;
③ 第10行到第14行代码分别输出各字段的值,其中第14行代码调用模块内的函数els(),返回当前局部变量的值;
④ 第15行代码调用FieldClass类中另外一个函数,设置相应字段的值;
⑤ 第16行到第20行代码分别输出各字段的值。
4.运行结果
按F5键,运行该程序,结果如图3-4所示
图3-4 实例3-3运行结果
2.属性
属性(Property)就像智能字段。属性通常具有带访问函数的专用数据成员,在语法上,属性被作为类的字段进行访问。
属性定义通常由以下两部分组成。
(1)专用数据成员的定义。示例如下:
Private number As Integer = 0
(2)使用属性声明语法对公共属性进行的定义。该语法通过get和set访问函数将专用数据成员和公共属性关联起来。示例如下:
Public Property MyNumber As Integer 'Retrieves number. Get Return number End Get 'Assigns to number. Set number = value End Set End Property
value这个术语是属性定义语法中的一个关键字。在属性代码中,将变量value分配给属性。value的类型必须与它被分配到的属性的声明类型相同。
虽然属性定义中通常包含专用数据成员,但这不是必需的。get访问器不用访问私有数据成员就可以返回值。get方法返回系统时间的属性就属于这种情况。属性启用数据隐藏,访问器方法隐藏属性的实现。示例如下:
Public Class SimpleProperty Private number As Integer = 0 Public Property MyNumber() As Integer ' Retrieves number. Get Return number End Get ' Assigns to number. Set number = value End Set End Property ' Other members... End Class Public Class UsesSimpleProperty Public Shared Sub Main() Dim example As New SimpleProperty() ' Sets the property. example.MyNumber = 5 ' Gets the property. Dim anumber As Integer = example.MyNumber
End Sub End Class
一般说来,get和set方法和其他方法没有什么不同。它们可以执行任何程序逻辑、引发异常,可以被重写以及用编程语言允许的任意修饰符进行声明。但是请注意,属性也可以是静态的。如果属性是静态的,则get和set方法可以实现的功能有一些局限性。
另外在创建类时,可以通过使用Default标识符,指定类的一个属性是默认的。如将上面的代码改写如下:
Public Class SimpleProperty
Private number As Integer = 0
Default Public Property MyNumber(ByVal a As Integer) As Integer
' Retrieves number.
Get
Return number
End Get
' Assigns to number.
Set(ByVal value As Integer)
number = value
End Set
End Property
' Other members...
End Class
Public Class UsesSimpleProperty
Public Shared Sub Main()
Dim example As New SimpleProperty()
' Sets the property.
example(0) = 5
' Gets the property.
Dim anumber As Integer = example(0)
MsgBox(anumber)
End Sub
End Class
在上例中定义MyNumber为默认属性时,必须注意不带必选参数的属性不能声明为“Default”。
属性的类型可以是基元类型、基元类型的集合、用户定义类型或用户定义类型的集合。对于所有基元类型,.NET Framework提供实现字符串到值转换的类型转换器。当属性可以使用类型转换器时,它显示在设计器的属性浏览器中。如果用户定义自定义属性并想让属性浏览器显示它们,则必须实现自定义类型转换器。
当属性的数据类型是枚举类型时,开发环境(如Microsoft Visual Studio .NET)在“属性”窗口中将该属性显示为下拉列表。如果属性的数据类型是具有属性的类,这些属性叫做定义属性的子属性。在Visual Studio .NET的“属性”窗口中,用户可以展开属性以显示其子属性。向属性添加特性也是十分重要,这样它们可以在设计时正确地显示在属性浏览器中。
如果需要决定是使用属性还是字段,还可以考虑以下准则。
· 当变量需要只读时,使用属性。
· 如果需要对是否超出数据类型有范围的有效性检验,使用属性。
· 如果变量改变对象的状态,使用属性。
· 如果这个变量变化,在类中的其他变量也需要变化,使用属性。
下面以实例说明属性的使用。