Visual Basic类与对象创建及实例化
Visual Basic 类的定义基础
类定义的语法结构
在 Visual Basic 中,类是一种用户自定义的数据类型,它封装了数据(字段和属性)和对数据进行操作的过程(方法)。定义一个类使用 Class
关键字,以下是一个简单的类定义结构示例:
Class MyClass
'字段(成员变量)
Private myField As Integer
'属性
Public Property MyProperty As Integer
Get
Return myField
End Get
Set(value As Integer)
myField = value
End Set
End Property
'方法
Public Sub MyMethod()
Console.WriteLine("This is MyMethod in MyClass.")
End Sub
End Class
在上述代码中,MyClass
是类的名称。myField
是一个私有字段,只能在类内部访问。MyProperty
是一个公共属性,提供了对私有字段 myField
的受控访问。MyMethod
是一个公共方法,可从类的外部调用。
访问修饰符
Private
:使用Private
修饰的成员(字段、属性、方法)只能在类的内部访问。例如上述代码中的myField
,外部代码无法直接访问它,这保证了数据的安全性和封装性。Public
:Public
修饰的成员可以从类的外部访问。像MyProperty
和MyMethod
,其他代码可以创建MyClass
的实例并访问这些公共成员。Friend
:Friend
修饰的成员在同一程序集内可以访问,但在程序集外部无法访问。这在大型项目中,当你希望某些类成员对同一项目中的其他代码可见,但对外部引用该程序集的代码不可见时非常有用。
类的成员详解
字段(成员变量)
- 定义与初始化:字段是类中声明的变量,用于存储类的状态信息。它们可以在声明时直接初始化,例如:
Class AnotherClass
Private count As Integer = 0
Private message As String = "Initial message"
End Class
- 作用域:字段的作用域取决于其访问修饰符。私有字段只能在类内部访问,而公共字段可以从类的外部访问。不过,通常建议将字段设为私有,并通过属性提供访问,以实现更好的数据封装。
属性
- 属性的作用:属性提供了一种灵活的方式来访问和修改类的字段。它们可以包含自定义的逻辑,例如验证输入值。属性可以分为只读属性(只有
Get
访问器)、只写属性(只有Set
访问器)和读写属性(同时有Get
和Set
访问器)。 - 只读属性示例:
Class Circle
Private radius As Double
Public Sub New(ByVal r As Double)
radius = r
End Sub
Public ReadOnly Property Area As Double
Get
Return Math.PI * radius * radius
End Get
End Property
End Class
在上述 Circle
类中,Area
属性是只读的,它根据 radius
字段计算圆的面积,外部代码只能获取该属性值,不能修改。
3. 只写属性示例:虽然只写属性不常见,但在某些场景下有用,例如在数据验证后只设置值而不允许读取。
Class PasswordClass
Private password As String
Public WriteOnly Property UserPassword As String
Set(value As String)
If value.Length >= 8 Then
password = value
Else
Throw New ArgumentException("Password must be at least 8 characters long.")
End If
End Set
End Property
End Class
这里的 UserPassword
属性是只写的,它验证输入的密码长度是否符合要求,符合则设置 password
字段。
方法
- 方法的定义与调用:方法是类中定义的过程,用于执行特定的操作。方法可以接受参数,也可以返回值。以下是一个简单的加法方法示例:
Class MathOperations
Public Function Add(ByVal num1 As Integer, ByVal num2 As Integer) As Integer
Return num1 + num2
End Function
End Class
要调用这个方法,可以这样写:
Dim mathObj As New MathOperations()
Dim result As Integer = mathObj.Add(3, 5)
Console.WriteLine("The result of addition is: " & result)
- 方法重载:在同一个类中,可以定义多个同名但参数列表不同的方法,这就是方法重载。例如:
Class Calculator
Public Function Add(ByVal num1 As Integer, ByVal num2 As Integer) As Integer
Return num1 + num2
End Function
Public Function Add(ByVal num1 As Double, ByVal num2 As Double) As Double
Return num1 + num2
End Function
End Class
这里 Calculator
类有两个 Add
方法,一个接受两个 Integer
类型参数,另一个接受两个 Double
类型参数。编译器会根据调用时传入的参数类型来决定调用哪个方法。
构造函数与析构函数
构造函数
- 构造函数的作用:构造函数是类中的特殊方法,用于在创建类的实例时初始化对象的状态。在 Visual Basic 中,构造函数名为
New
。 - 默认构造函数:如果类中没有显式定义构造函数,Visual Basic 会提供一个默认的无参数构造函数。这个默认构造函数会将所有字段初始化为其默认值(数值类型为 0,字符串类型为
Nothing
等)。 - 自定义构造函数:当需要对对象进行特定的初始化时,就需要定义自定义构造函数。例如:
Class Person
Private name As String
Private age As Integer
Public Sub New(ByVal pName As String, ByVal pAge As Integer)
name = pName
age = pAge
End Sub
Public Sub DisplayInfo()
Console.WriteLine("Name: " & name & ", Age: " & age)
End Sub
End Class
要创建 Person
类的实例并初始化其属性,可以这样做:
Dim person1 As New Person("John", 30)
person1.DisplayInfo()
析构函数
- 析构函数的作用:析构函数在对象被垃圾回收器回收之前执行清理操作,例如释放非托管资源(如文件句柄、数据库连接等)。在 Visual Basic 中,析构函数名为
Finalize
。 - 示例:
Class ResourceHolder
Private fileHandle As Integer
Public Sub New(ByVal filePath As String)
fileHandle = File.OpenHandle(filePath)
End Sub
Protected Overrides Sub Finalize()
File.CloseHandle(fileHandle)
MyBase.Finalize()
End Sub
End Class
在上述代码中,ResourceHolder
类在构造函数中打开一个文件并获取文件句柄,在析构函数 Finalize
中关闭文件句柄以释放资源。需要注意的是,垃圾回收的时机是不确定的,因此不能依赖析构函数来执行对时间敏感的清理操作。
对象的创建与实例化
使用 New
关键字创建对象
- 基本语法:在 Visual Basic 中,使用
New
关键字来创建类的实例。例如,对于前面定义的MyClass
类,可以这样创建实例:
Dim myObject As New MyClass()
这行代码做了两件事:首先,它声明了一个名为 myObject
的变量,其类型为 MyClass
;然后,使用 New
关键字创建了 MyClass
的一个实例,并将该实例的引用赋给 myObject
变量。
2. 创建对象并初始化属性:如果类有自定义构造函数,可以在创建对象时传入参数来初始化对象的属性。例如对于 Person
类:
Dim person2 As New Person("Jane", 25)
对象引用与内存管理
- 对象引用:当使用
New
关键字创建对象时,实际上是在内存中分配了一块空间来存储对象的数据,而变量只是持有对该对象的引用。例如:
Dim obj1 As New MyClass()
Dim obj2 As obj1
这里 obj1
和 obj2
都引用了同一个 MyClass
实例。如果通过 obj2
修改对象的属性,obj1
所引用的对象也会反映出这些变化。
2. 内存管理:Visual Basic 使用垃圾回收机制来管理内存。当一个对象不再有任何引用指向它时,垃圾回收器会在适当的时候回收该对象所占用的内存。例如:
Dim tempObj As New MyClass()
tempObj = Nothing
这里将 tempObj
设置为 Nothing
,表示不再引用 MyClass
的实例,垃圾回收器最终会回收该实例占用的内存。不过,对于需要手动释放的非托管资源,如前面提到的文件句柄,需要在析构函数或专门的清理方法中进行处理。
类的继承
继承的概念与语法
- 继承的概念:继承允许一个类(子类)从另一个类(父类)中获取成员(字段、属性、方法等)。子类可以继承父类的特性,并可以添加自己的新成员或重写父类的成员。这有助于代码的复用和创建层次化的类结构。
- 继承的语法:使用
Inherits
关键字来实现继承。例如:
Class Animal
Public Property Name As String
Public Sub MakeSound()
Console.WriteLine("The animal makes a sound.")
End Sub
End Class
Class Dog
Inherits Animal
Public Sub Bark()
Console.WriteLine("The dog barks.")
End Sub
End Class
在上述代码中,Dog
类继承自 Animal
类,因此 Dog
类拥有 Animal
类的 Name
属性和 MakeSound
方法,同时 Dog
类还添加了自己的 Bark
方法。
重写方法
Overridable
和Overrides
关键字:如果父类中的方法允许子类重写,需要在父类方法定义中使用Overridable
关键字。子类重写该方法时,使用Overrides
关键字。例如:
Class Shape
Public Overridable Function Area() As Double
Return 0
End Function
End Class
Class Circle
Inherits Shape
Private radius As Double
Public Sub New(ByVal r As Double)
radius = r
End Sub
Public Overrides Function Area() As Double
Return Math.PI * radius * radius
End Function
End Class
这里 Shape
类的 Area
方法被声明为 Overridable
,Circle
类继承自 Shape
类并重写了 Area
方法来计算圆的面积。
多态性
- 多态的概念:多态性是指不同类的对象对同一消息(方法调用)做出不同响应的能力。在 Visual Basic 中,通过继承和方法重写来实现多态性。例如:
Dim shapes() As Shape = {New Circle(5), New Shape()}
For Each shape In shapes
Console.WriteLine("Area: " & shape.Area())
Next
在上述代码中,shapes
数组包含了 Circle
类和 Shape
类的实例。当调用 Area
方法时,会根据对象的实际类型来调用相应的 Area
方法实现,这就是多态性的体现。
接口与抽象类
接口
- 接口的定义:接口是一种特殊的抽象类型,它只定义方法、属性等成员的签名,而不包含实现。接口使用
Interface
关键字定义。例如:
Interface IPrintable
Sub Print()
End Interface
Class Document
Implements IPrintable
Public Sub Print() Implements IPrintable.Print
Console.WriteLine("Printing document...")
End Sub
End Class
这里 IPrintable
接口定义了一个 Print
方法,Document
类实现了该接口,并提供了 Print
方法的具体实现。
2. 接口的作用:接口允许多个不相关的类实现相同的行为,从而实现更灵活的多态性。例如,不同类型的对象(如文档、图像等)都可以实现 IPrintable
接口,以便在需要打印的地方统一处理。
抽象类
- 抽象类的定义:抽象类是一种不能被实例化的类,它可以包含抽象方法(只有声明,没有实现)和非抽象方法。抽象类使用
MustInherit
关键字定义,抽象方法使用MustOverride
关键字定义。例如:
MustInherit Class AbstractShape
Public MustOverride Function Area() As Double
Public Sub DisplayInfo()
Console.WriteLine("This is an abstract shape.")
End Sub
End Class
Class Rectangle
Inherits AbstractShape
Private width As Double
Private height As Double
Public Sub New(ByVal w As Double, ByVal h As Double)
width = w
height = h
End Sub
Public Overrides Function Area() As Double
Return width * height
End Function
End Class
这里 AbstractShape
是一个抽象类,它有一个抽象方法 Area
和一个非抽象方法 DisplayInfo
。Rectangle
类继承自 AbstractShape
类,并实现了 Area
方法。
2. 抽象类与接口的区别:抽象类可以包含实现代码和成员变量,而接口只能包含成员的声明。一个类只能继承一个抽象类,但可以实现多个接口。抽象类适用于当存在一些共同的行为或状态需要在子类中共享时,而接口适用于当需要为不相关的类提供统一的行为定义时。
泛型类与对象
泛型类的定义
- 泛型的概念:泛型允许你创建可以与不同数据类型一起工作的类、方法等,而无需为每种数据类型创建单独的版本。这提高了代码的复用性和类型安全性。
- 泛型类的语法:定义泛型类时,在类名后面使用尖括号
<>
来指定类型参数。例如:
Class GenericList(Of T)
Private items() As T
Private count As Integer = 0
Public Sub Add(ByVal item As T)
If count = items.Length Then
Array.Resize(items, count + 1)
End If
items(count) = item
count += 1
End Sub
Public Function GetItem(ByVal index As Integer) As T
If index < 0 Or index >= count Then
Throw New IndexOutOfRangeException()
End If
Return items(index)
End Function
End Class
这里 GenericList(Of T)
是一个泛型类,T
是类型参数。这个类可以用于存储任何类型的对象,并提供了添加和获取对象的方法。
使用泛型类创建对象
- 实例化泛型类:要使用泛型类,需要在实例化时指定实际的类型参数。例如:
Dim intList As New GenericList(Of Integer)()
intList.Add(10)
intList.Add(20)
Dim value As Integer = intList.GetItem(0)
Console.WriteLine("The value is: " & value)
这里创建了一个 GenericList(Of Integer)
的实例,用于存储 Integer
类型的数据。同样,也可以创建用于存储其他类型数据的实例,如 GenericList(Of String)
等。
2. 泛型类的优势:泛型类减少了代码的重复,同时在编译时提供了类型检查,提高了程序的安全性和性能。相比于使用 Object
类型来处理多种数据类型,泛型避免了装箱和拆箱操作,从而提高了效率。
总结 Visual Basic 类与对象相关要点
通过以上对 Visual Basic 类与对象创建及实例化的详细阐述,我们了解了类的定义、成员的种类、对象的创建与使用,以及继承、接口、抽象类和泛型等重要概念。这些知识构成了 Visual Basic 面向对象编程的核心内容,熟练掌握它们对于开发高质量、可维护和可扩展的应用程序至关重要。在实际编程中,要根据具体的需求和场景,合理运用这些特性,以实现最佳的编程效果。无论是开发小型的桌面应用程序,还是大型的企业级系统,对类与对象的深刻理解和灵活运用都将是成功的关键。在日常编码实践中,不断练习和尝试不同的面向对象设计模式,结合实际项目需求优化代码结构,能够进一步提升编程技能和解决复杂问题的能力。希望通过本文的学习,读者能够在 Visual Basic 的面向对象编程领域迈出坚实的步伐,创造出更加优秀的软件作品。