目录
为什么窗体中无论是public,还是private都只在窗体内有效,而标准模块则不同
模块
模块简介
在VB(Visual Basic)编程中,模块是一种组织和封装代码的方式。它可以包含变量、常量、函数、子程序等多种元素,帮助开发人员将代码划分为逻辑上独立的部分。
在VB中有三种类型的模块,分别是窗体模块、标准模块和类模块。
窗体模块
窗体模块中包含了窗体以及窗体中所有控件的事件过程,文件扩展名为(*.frm),窗体文件中不仅包含窗体对象的外观设计,也包含窗体模块(Form Module)。窗体是一种全局范围的模块,其中的成员可以在整个项目中访问和调用。窗体模块是用于创建窗体的模块。在VB中,窗体通常对应于用户界面中的一个窗口或对话框。窗体模块包含与窗体相关联的代码,例如按钮的点击事件、文本框的输入验证等。窗体模块中的代码用于响应用户的操作并控制窗体的行为。每个窗体通常都有自己的窗体模块,用于处理与该窗体相关的逻辑。
标准模块
在一个工程中,某些代码要被多个窗体或设计器共同使用,就可以将这些代码存储在一个标准模块(Standard Module)中,其文件扩展名为(*.bas)。标准模块中只含有代码。程序一运行就加载模块,它的函数和变量是全局的,随时可以调用。标准模块是VB中最常见的模块类型之一。它用于存放函数、子过程和全局变量等。标准模块中的成员可以通过模块名直接访问,无需实例化模块。这使得标准模块成为存放通用的、应用程序范围内可共享的代码的理想位置。例如,可以在标准模块中定义一些公用的辅助功能或处理数据的函数。
类模块
类模块用于定义类,并包含类的成员和行为。 如果要创建自己定义的对象,就要首先创建一个类模块(Class Module)。类模块中包含了自定义的属性、方法和事件的定义及其实现。它是数据和代码的结合体,可以将其理解为是没有物理表现的控件。其文件扩展名为(*.cls)。类模块就是一个类,要实例化对象才能调用它的函数。类是VB中的核心概念之一,它用于创建对象的蓝图。类模块中可以定义属性、方法、事件和字段等。通过实例化类,可以创建类的对象,并使用类的成员来访问和操作对象的数据和行为。类模块提供了一种面向对象的编程方式,使代码更加结构化、可维护和可重用。
这些模块类型在VB中有不同的用途和限制。标准模块主要用于存放通用的代码和全局变量。窗体模块用于处理与特定窗体相关的逻辑和交互。类模块则用于定义类并封装相关的数据和功能。深入学习每种模块类型的特点和用法,可以帮助你在VB中更好地组织和管理代码。
区别
窗体模块 | 标准模块 | 类模块 | |
定义 | 用于创建和管理用户界面的模块 | 用于存放过程和函数的模块 | 用于定义对象的模块 |
扩展名 | .frm | .bas | .cls |
可见性 | 可见 | 可见 | 可见 |
实例化 | 可以实例化为窗体对象 | 不可实例化 | 可以实例化为类对象 |
继承性 | 可以继承其他窗体 | 不可继承 | 可以继承其他类 |
事件处理 | 可以处理窗体事件 | 无需处理事件 | 可以处理类事件 |
控件访问 | 可以直接访问窗体上的控件 | 无法直接访问窗体上的控件 | 可以通过属性或方法访问类中 的控件 |
生命周期 | 有加载、显示、关闭等生命周期事件 | 无生命周期事件 | 无生命周期事件 |
作用 | 用于创建用户界面和处理用户交互 | 用于存放通用的过程和函数 | 用于封装数据和行为的对象 |
作用域
在VB中,作用域描述了变量、常量和其他程序元素的可见性和有效性范围。作用域规定了程序中可以访问这些元素的地方。简单说就是一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
模块级别的作用域
在标准模块中定义的变量和常量具有模块级别的作用域。这意味着它们在整个模块内部都可见和访问,包括模块中定义的所有过程(函数和子程序)。模块级别的变量和常量在整个模块的任何地方都可以使用,不受过程的限制。
Module MyModule
Public Const PI As Double = 3.14159
Sub Main()
Dim radius As Double = 5
Dim area As Double = PI * radius * radius
Console.WriteLine("圆的面积为:" & area)
End Sub
End Module
在上面的示例中,PI
常量是在模块级别声明的,因此在Main
过程中可以直接使用它进行计算。
过程级别的作用域
过程级别的作用域是指在子程序(函数和子程序)中定义的变量和参数所具有的作用域。在VB中,过程级别的变量和参数只在声明它们的过程内部可见和访问,并且在过程结束时被销毁。
Module MyModule
Public Const PI As Double = 3.14159
Sub Main()
Dim radius As Double = 5
Dim area As Double = PI * radius * radius
Console.WriteLine("圆的面积为:" & area)
End Sub
End Module
常见问题
为什么窗体中无论是public,还是private都只在窗体内有效,而标准模块则不同
答案来源于标准模块的作用
简单的应用程序可以只有一个窗体,应用程序的所有代码都驻留在窗体模块中。而当应用程序庞大复杂时,就要另加窗体。最终可能会发现在几个窗体中都有要执行的公共代码。因为不希望在两个窗体中重复代码,所以要创建一个独立模块,它包含实现公共代码的过程。独立模块应为标准模块。此后可以建立一个包含共享过程的模块库。
在VB中,窗体是一种特殊的对象,它作为用户界面的容器,可以包含其他控件和元素。由于窗体通常用于显示用户界面,因此窗体中的成员(如控件、变量、方法等)默认情况下具有私有的访问修饰符。
当在窗体中声明一个成员时,如果没有明确指定访问修饰符(如Public、Private),则默认为Private。这意味着该成员只能在窗体内部访问,对于其他模块来说是不可见的。
标准模块是一种全局范围的模块,其中的成员默认情况下具有公共的访问修饰符(Public)。这意味着标准模块中的成员可以在整个项目中被访问和调用,不受限于特定的作用域。
通过这种设计,VB提供了一种方式来控制和管理代码的访问权限。在窗体中,我们可以将一些只希望在窗体内部使用的成员声明为私有,以保护其安全性并防止误用。而标准模块则更适合用于存储和共享全局的数据、函数和过程,以便在整个项目中重用和调用。
注意,可以显式地在窗体中使用Public访问修饰符来声明公共成员,从而使其在其他模块中可见。
Public Class MyForm
Public labelText As String
Private Sub Button_Click(sender As Object, e As EventArgs) Handles Button.Click
labelText = TextBox.Text
MessageBox.Show("Label Text: " & labelText)
End Sub
End Class
Module MyModule
Sub Main()
Dim form As New MyForm()
form.ShowDialog()
Console.WriteLine("Label Text from outside the form: " & form.labelText)
End Sub
End Module
在上述代码中,在MyForm
窗体类中声明了一个名为labelText
的公共成员,使用Public修饰符来使其可见和访问。这个成员是一个字符串类型的变量,用于存储窗体中的标签文本。
在Button_Click
事件处理程序中,将文本框中输入的值赋给labelText
变量,并通过消息框显示出来。
在MyModule
模块中,创建了MyForm
的实例并显示出来。然后,在代码的后续部分,可以在窗体以外的位置访问form.labelText
,输出窗体中标签的文本值。
这里注意,公共成员在窗体以外的代码中可以被访问,但如果窗体对象不可见或未实例化,则无法直接访问该成员。在示例代码中,我创建了MyForm
的实例,并通过该实例访问了labelText
成员。
标准模块中,成员的默认访问修饰符是Public,不能使用Private来限制成员的可见性。只能使用Public、Friend、Protected等访问修饰符来控制成员的访问权限。这些访问修饰符的使用可以根据具体需求进行调整,以实现代码的封装和逻辑的隔离。
下面是一个示例代码,说明在标准模块(Module)中成员的默认访问修饰符是Public:
Module MyModule
Public Sub PublicMethod()
Console.WriteLine("This is a public method.")
End Sub
Sub DefaultMethod()
Console.WriteLine("This is a default (public) method.")
End Sub
' Private Sub PrivateMethod() ' 这行代码会导致编译错误
' Console.WriteLine("This is a private method.")
' End Sub
End Module
在上述代码中,PublicMethod
和DefaultMethod
两个子程序声明为Public和默认访问修饰符,它们在整个项目中都可以被其他模块调用和访问。如果尝试使用Private来修饰PrivateMethod
,则会导致编译错误,因为Private不是标准模块成员的有效访问修饰符。
以上代码仅用于说明访问修饰符在标准模块中的可用性,并不代表最佳实践。在实际开发中,要根据需要选择适当的访问修饰符来控制成员的可见性和访问范围。
限定符的使用
VB提供了一些限定符(Qualifier)来明确指定变量或成员所属的模块或类。例如,使用Me
关键字限定当前类的成员,使用类名限定模块中的成员等。了解如何正确使用限定符可以避免命名冲突和增加代码的可读性。
当涉及到使用限定符时,可以通过以下几种方式来明确指定变量或成员所属的模块或类。
使用模块名限定:在VB中,可以使用模块名直接访问模块级别的成员,无需实例化模块。例如,假设有一个标准模块(Standard Module)名为MyModule
,其中定义了一个函数MyFunction
,那么可以通过以下方式调用该函数:
Dim result As Integer
result = MyModule.MyFunction()
使用类名限定:对于类中的成员,可以使用类名来限定访问。假设有一个类名为MyClass
,其中定义了一个属性MyProperty
,那么可以通过以下方式访问和设置该属性:
Dim myObj As New MyClass()
myObj.MyProperty = 10
Console.WriteLine(myObj.MyProperty)
使用Me
关键字:在类内部,可以使用Me
关键字来引用当前类的实例。这在类的构造函数或方法中特别有用。例如,假设有一个类名为MyClass
,其中定义了一个方法Calculate
,那么可以通过以下方式在方法内部访问类的成员:
Class MyClass
Private value As Integer
Public Sub Calculate()
' 使用 Me 关键字引用当前类的实例
Me.value = 10
Dim result As Integer = Me.value * 2
Console.WriteLine(result)
End Sub
End Class
通过使用限定符,可以明确指定变量或成员所属的模块或类,消除命名冲突,并提高代码的可读性和可维护性。在编写VB代码时,根据变量或成员所在的模块或类来选择适当的限定符,有助于代码的组织和清晰度。
其他常见问题
-
模块和类之间的区别:有时候可能会混淆模块(Module)和类(Class)的概念。在VB中,模块是一种特殊的类,不能创建实例,而类可以实例化。模块通常用于容纳函数、子过程和全局变量,而类通常用于创建对象和封装相关的数据和功能。
-
不同类型的模块:VB中有多种类型的模块,如标准模块(Standard Module)、窗体模块(Form Module)和类模块(Class Module)。每种模块类型都有其特定的用途和限制。了解这些模块类型之间的区别和用法是很重要的。
-
变量的作用域:在VB中,变量的作用域决定了它可以被访问的范围和时间。常见的作用域包括局部作用域(Local Scope)、模块级作用域(Module-Level Scope)和全局作用域(Global Scope)。理解这些不同的作用域以及变量在这些作用域内的生命周期是至关重要的。
总结
模块是组织和封装代码的逻辑单元,而作用域定义了代码中标识符(变量、函数名等)的可见性和可访问性范围。模块作用域指的是模块内部定义的标识符的可见性范围,而局部作用域指的是特定代码块内定义的标识符的可见性范围。全局作用域则指的是整个程序中定义的标识符的可见性范围。理解这些概念,有助于我们编写更具结构性、可维护性和可读性的代码。