配色: 字号:
《Visual Basic 2005 程序设计》第6章 面向对象技术
2023-05-25 | 阅:  转:  |  分享 
  
第6章 面向对象技术本章主要内容:理解面向对象的概念和特征。熟悉类、属性、方法的定义。初步应用类和对象。理解构造函数和析构函数。进一步理解
事件。初步应用事件。理解并初步实现继承和多态。6.1 面向对象基本概念面向对象程序设计与传统的结构化程序设计是不同的,它将实际生活
中的各种事物都看作是对象,并将对象作为程序设计的关键,因此,符合人类认识世界的思维特点。每个对象既有自己的状态和属性,又有相应的行
为和动作。如何利用抽象化思维和语言工具获得程序中使用的对象则是面向对象程序设计的核心技术。为了能更好地理解和运用面向对象技术,本章
在后续的内容中通过不断完善学生这个类和相应对象进行介绍。6.1.1 类与对象要掌握面向对象技术,首先要知道什么是对象和类。在第1章
中已经提到窗体类及其对象(frmHelloWorld)和Button类及其对象(btnSayHello、btnQuit),因此我们
知道,对象是类的实例,类是对象的抽象描述。这里我们以学生为例进一步说明类和对象的概念。例如:在学生信息管理软件中,处理的数据主要是
每个学生的各类信息,因此,可以把每个学生的相关信息及对这些信息的处理看成是一个整体,即一个对象。在面向对象程序设计中,可以按照下面
的步骤进行分析:⑴ 针对每一个具体的学生,我们可以分析其包含的属性和行为,属性可能有:学号、姓名、性别、出生日期、政治面貌、专业、
成绩、借书数量、所借书目列表、头发颜色、眼睛大小、DNA、牙齿个数等等;行为可能有:信息注册、信息浏览、退学、借书、还书、考试、打
球、跑步、听歌、上网等。⑵ 根据(1)列出的每个具体学生的属性和行为,结合学生信息管理软件中对学生信息的需求,挑选出在该软件中必须
处理的信息和行为,把这些属性和行为放到一起,即描述为学生类:学生类{ 属性:学号、姓名、专业、借书数量、所借书目列表; 行为:
信息注册、信息浏览、借书、娱乐;}可以看出,通过具体的学生信息抽象出的学生类,包含的属性和行为比具体的学生的属性和行为少,这是因为
在该软件中,对于每个具体的学生,只关注学生类中描述的这些属性和行为,其它属性和行为可以忽略不考虑。⑶ 在程序中以⑵中抽象出的学生类
为类型(自定义类型),创建具体的学生对象,每个学生对象即为学生类的一个实例。这些学生对象包含的属性和行为,即为学生信息管理软件中管
理的每个学生的属性和行为。对“具体学生→学生类→学生对象”的分析过程如图6-1所示。 6.1.2 面向对象基本特征Visual B
asic 2005作为可视化的面向对象编程语言,很好地支持了面向对象的三个基本特征:封装、继承和多态。例如,工具箱中的按钮Butt
on类包含有Name(名字标识)、Text(显示文本)、ForeColor(前景色)、Size(大小)、Location(位置)等
属性和Click(单击)等事件声明,因此,可提供给用户直接使用,而用户并不需要了解Button类内部的具体实现;同时也有利于开发者
调试和维护。这就是封装的体现。如果希望创建个性化的按钮,则可继承原来的Button类生成新的按钮类,不需要全部重新开发新按钮类,从
而通过重用已有的类,并进一步添加修改来实现新的类,因此,可提高软件开发效率,减少工作量。如果新旧按钮类有不同的Play方法,当发出
Play操作后,对应新旧按钮类的不同对象会自动选择自己的Play方法来执行,得到不同的效果。这就是多态的体现。以学生为例,进一步理
解面向对象的三个基本特征。通过对所有学生个体进行抽象可得到学生类,例如所有学生都有学号、姓名、专业、借书数量与所借书目列表等属性和
信息注册、信息浏览、借书与娱乐等行为,因此构建的学生类就封装了上述信息,图6-1中的学生类已经体现了信息的封装。学生中有科协成员和
合唱团成员,于是可通过继承学生类的方式实现科协成员类和合唱团成员类,这时科协成员类和合唱团成员类可以继承学生类原有的属性和方法,并
进一步修改或扩展科协成员类和合唱团成员类的相关信息,例如假定最初学生类没有娱乐行为,那么科协成员类和合唱团成员类可以在原有学生类的
行为基础上分别增加上网和听音乐的行为,图6-2描述了这种继承机制。学生个体的娱乐行为是不同的。同样是娱乐,张三可能上网,李四可能听
音乐,王五可能打球,呈现出多态,例如假定最初学生类有娱乐行为,而科协成员类和合唱团成员类在继承原有学生类的同时重新定义了各自的娱乐
行为,即科协成员上网和合唱团成员听音乐。这时如果张三是科协成员, 那么他的娱乐行为就是上网;如果张三是合唱团成员, 那么他的娱乐行
为就是听音乐,这种自动选择娱乐行为的效果就是多态机制的体现,如图6-3所示。6.2 初步应用类和对象为了让大家有直观的认识,我们以
Visual Basic 2005为例介绍前面提到的学生类的创建和初步应用,包括如何定义类及其成员(属性、方法)。 6.2.1 定
义类定义类的基本形式是: Class 类名 …… End Class通常,和类相关的所有信息都应包括在其中,包括各种属性和相关的
方法。有了类定义,就可以创建该类的对象。创建对象的基本形式是: Dim 对象名 As New 类名例6.1 建立学生类,其中包括
学生的学号、姓名、专业基本信息。具体操作过程:⑴ 新建项目,选择“Windows应用程序”,把“名称”修改为“学生基本信息”,然后
单击“确定”,并在解决方案资源管理器中将Form1.vb修改为frmStudent.vb。⑵ 打开窗体设计视图,选择frmStud
ent窗体,并在属性框中修改窗体的属性:StartPosition为“CenterScreen”;Text为“学生基本信息”。⑶
在“项目”菜单中单击“添加类”,弹出“添加新项”对话框,把类“名称”改为“Student.vb”, 然后单击“添加”。⑷ 在“St
udent.vb”代码设计视图中依次添加strNo、strName和strMajor信息。Public Class Student
''定义学生学号、姓名、专业基本信息Dim strNo As String Dim strName As
String Dim strMajor As String End Class提示:类中用Dim 定义变量
信息,也可用Private,其作用相同。建议不要用Public定义变量,这将会破坏类的封装性,这是因为用Public定义的变量将对
类外公开。6.2.2定义属性我们知道,工具箱中的控件有许多属性,例如按钮Button的属性Text表示按钮上显示的文本信息,使用时
既可读取Text属性,也可修改该属性。定义属性的标准方式是在类中使用Property语句,基本形式是:Public Propert
y 属性名( ) As 属性类型 …… Get …… Return 属性值 End Get Set(参数value
) …… End Set ……End Property其中Get部分用于返回属性值,不需要提供参数,可利用Return语句
返回属性值;Set部分用于设置/修改属性值,通常有一个参数value将其值传递给该属性。例6.2 考虑到学生借阅图书的情况,假定
每个学生最多借10本书。在学生类中定义一个私有变量intBTotal,表示目前学生已借图书的总数,初值为0;同时增加一个表示学生已
借书总数的属性intTotal,然后在窗体中访问该属性。具体操作过程:⑴ 新建项目,选择“Windows应用程序”,把“名称”修改
为“图书总数属性”,然后单击“确定”,并在解决方案资源管理器中将Form1.vb修改为frmStudent.vb。⑵ 将窗体frm
Student的Text属性改为“图书总数属性”。 ⑶ 添加学生类Student,具体操作过程同例6.1。⑷ 在“Student.
vb”的代码编辑器中,往Student类中添加定义私有变量intBTotal和属性intTotal的代码: Public Clas
s Student Private strNo As String ''定义学生学号、姓名、专业基本信息 Private
strName As String Private strMajor As StringPrivate intBTotal
As Integer=0 ''学生已借图书的总数Public Property intTotal() As Intege
rGet Return intBTotal End GetSet(ByVal value As Inte
ger) If value < 0 Then value = 0 ''intBTotal的值在0-10之间
If value > 10 Then value = 10 intBTotal =
value End SetEnd PropertyEnd Class⑸ 在“frmStudent.vb”的代码编辑器
中,往frmStudent类中添加生成Student类的对象stuZhangsan的代码:Public Class frmStud
ent Dim stuZhangsan As New Student ''新建Student类的对象stuZha
ngsanEnd Class⑹ 为窗体添加1个Label控件和1个TextBox控件,将Label控件的Text改为“当前属性值:
”,将TextBox控件的Name改为“txtTotal”。⑺ 为窗体添加2个Button控件,将Name分别改为“btnGet”
、 “btnSet”,Text分别改为“读取”、“设置”。⑻ 双击“读取”按钮,在“读取”按钮Click事件过程中添加响应代码:P
rivate Sub btnGet_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnGet.Click txtTotal.Text = stuZ
hangsan.intTotal() ''读取属性End Sub⑼ 双击“设置”按钮,在“设置”按钮Click事件过程中添
加响应代码:Private Sub btnSet_Click(ByVal sender As System.Object, ByV
al e As System.EventArgs) Handles btnSet.Click stuZhangsan.
intTotal() = txtTotal.Text ''设置属性End Sub可能有人会问:学生怎能自己修改intTotal
属性呢?的确如此,因此需要对intTotal属性进行限制,即不能修改,但可以读取。这实际上是要求创建只读属性,标准的做法是在属性定
义语句中加入ReadOnly,即Public Readonly Property intTotal() As Integer,此时
属性定义中只有Get部分,不出现Set部分。类似地,可以加入WriteOnly来创建只写属性,即Public WriteOnly
Property intTotal() As Integer,此时属性定义中只有Set部分,不出现Get部分,即属性只能修改,但不
能读取。6.2.3 定义方法关于类方法,其实在前面讲述的内容中一直在使用。例如窗体Form就有常见的方法Show和Hide,分别用
于窗体的显示和隐藏,通过方法Close关闭窗体并退出程序执行等。通常在类中定义的函数或过程就是方法。要使用类方法,一般需要先用ne
w生成该类的对象实例,然后利用对象调用对应的方法。但共享方法例外,使用共享方法时不需要创建该类的对象实例,直接从类调用共享方法,定
义共享方法时需在方法前加入Shared修饰符。例如数组类Array的排序方法Sort就是共享方法。例6.3 在例6.1学生类中添
加方法InputStuInfo和OutputStuInfo,利用对话框录入显示学生基本信息。具体操作过程:⑴ 新建项目,选择“Wi
ndows应用程序”,并把“名称”修改为“学生基本信息显示方法”,然后单击“确定”,并在解决方案资源管理器中将Form1.vb修改
为frmStudent.vb。⑵ 将窗体frmStudent的Text属性改为“学生基本信息显示方法”。⑶ 添加学生类Studen
t,具体操作过程同例6.1。⑷ 在“Student.vb”的代码编辑器中,往Student类中添加方法InputStuInfo和O
utputStuInfo的代码:Public Class Student …… Public Sub InputSt
uInfo() strNo = InputBox("请输入学号", "学生基本信息录入") strNam
e = InputBox("请输入姓名", "学生基本信息录入") strMajor = InputBox("请
输入专业", "学生基本信息录入")End Sub Public Sub OutputStuInfo() Dim s
trInfoStr As String strInfoStr = "基本信息:" & vbNewLine & "学号
:" & strNo & vbNewLine & "姓名:" & strName & vbNewLine & "专业:" & st
rMajor MessageBox.Show(strInfoStr, "学生基本信息显示", MessageBoxB
uttons.OK) End SubEnd Class提示:调用InputBox时,在一对话框中显示提示,等待用户输入文字或单击按
钮,然后返回包含文本框内容的字符串。InputBox的调用格式为:Public Function InputBox( _ B
yVal Prompt As String, _ Optional ByVal Title As String = "",
_ Optional ByVal DefaultResponse As String = "", _ Optional
ByVal Xpos As Integer = -1, _ Optional ByVal YPos As Integer
= -1 _) As String参数的含义:Prompt:必选,以消息形式显示在对话框中的 String 表达式。如果 Prom
pt 包含多行,则可以在每行之间使用回车字符 (Chr(13))、换行符 (Chr(10)) 或者回车/换行符的组合 (Chr(1
3) & Chr(10)) 来分隔各行。Title: 可选,显示在对话框标题栏中的 String 表达式。如果省略 Title,则
将应用程序名放在标题栏中。DefaultResponse :可选,显示在文本框中的 String 表达式,在没有提供其他输入时作为
默认响应。如果省略 DefaultResponse,则显示的文本框为空。XPos:可选。数值表达式,以缇为单位指定对话框的左边与屏
幕左边的距离。如省略 XPos,对话框将水平居中。YPos :可选,数值表达式,以缇为单位指定对话框的上边与屏幕上边的距离。如果省
略 YPos,则对话框位于在屏幕垂直方向距下边缘大约三分之一处。⑸在“frmStudent.vb”的代码编辑器中,往frmStud
ent类中添加生成Student类的对象stuZhangsan的代码:Public Class frmStudent Dim st
uZhangsan As New Student ''新建Student类的对象stuZhangsanEnd Class⑹
双击frmStudent窗体,在frmStudent窗体Load事件过程中添加响应代码:Private Sub frmStuden
t _Load(ByVal sender As System.Object, _ ByVal e As System.EventA
rgs) Handles MyBase.LoadstuZhangsan.InputStuInfo() stuZhan
gsan.OutputStuInfo()End Sub 例6.4 以学生借书为例。在学生类中添加私有变量altBList和方法B
orrowBook,altBlist表示目前学生已借图书的列表,BorrowBook表示学生借书同时修改altBlist,一次可借
1本,也可借多本,但最多不超过10本。用方法BorrowBook实现不同的借书情况,并在窗体上显示相关信息。具体操作过程:⑴ 新建
项目,选择“Windows应用程序”,把“名称”修改为“学生借书方法”,然后单击“确定”,并在解决方案资源管理器中将Form1.v
b修改为frmStudent.vb。⑵ 将窗体frmStudent的Text属性改为“学生借书方法”。⑶ 添加学生类Student
,具体操作过程同例6.2。⑷ 在“Student.vb”的代码编辑器中,往Student类中添加方法InputStuInfo和Ou
tputStuInfo和定义数组altBList的代码:Public Class Student ''定义学生学号、姓名、专业基本
信息 Private strNo As String Private strName As String Pri
vate strMajor As String Private intBTotal As Integer = 0
''学生已借图书的总数Private altBList As New ArrayList() ''学生已借图书的书目列表,下标
为0-9 Public Sub BorrowBook(ByRef strBNO As String) intBTot
al = intBTotal + 1 If (intBTotal < 11 And strBNO <> "") Then
''已借图书总数最多10本且所借书名不为空 altBList.Add(strBNO)
MessageBox.Show("借书一本操作成功!", "有效操作", MessageBoxButtons.OK)
Else intBTotal = intBTotal - 1 MessageBox
.Show("对不起,借书总数已到最大值或书名空白!", "无效操作", MessageBoxButtons.OK)
End IfEnd Sub Public Sub BorrowBook(ByRef altBNOlist As ArrayLis
t) ''学生一次借阅图书的书目列表 intBTotal = intBTotal + altBNOlis
t.Count If (intBTotal < 11 And altBNOlist.Count <> 0) Then
''已借图书总数最多10本且添加所借书目列表不为空 altBList.AddRange(altBNOlis
t) MessageBox.Show("借书登记操作成功!", "有效操作", MessageBoxButt
ons.OK) Else intBTotal = intBTotal - altBNOlist
.Count MessageBox.Show("对不起,借书总数已到最大值或书名列表空白!", "无效操作"
, MessageBoxButtons.OK) End If End SubEnd Class⑸ 为窗体添加3
个Label控件,分别将Text改为“可借阅书目列表(请在所借书目前打勾):”、“选择的书目列表”和“输入1本书名:”;添加1个T
extBox控件,将Name改为“txtOneBName”;添加1个ListBox控件,将Name改为“lbxBListed” ,
MultiColumn改为“True”;添加1个CheckedListBox控件,将Name改为“clbBList”,CheckO
nClick改为“True”,MultiColumn改为“True”,并在Items字符串集合编辑器中依次输入15个书名,每行一个
。⑹ 为窗体添加2个Button控件,分别将Name改为“btnBorrow”和“btnBorrowOne”,将Text改为“借阅
”和“借阅一本”。⑺ 在frmStudent类中生成Student类的对象stuZhangsan,即在Public Class f
rmStudent后添加代码:Dim stuZhangsan As New Student ''新建Student类的对象s
tuZhangsan。⑻ 双击“借阅”按钮,在“借阅”按钮Click事件过程中添加响应代码:Private Sub btnBorr
ow_Click(ByVal sender As System.Object, ByVal e As System.EventAr
gs) Handles btnBorrow.ClickDim altBookList As New ArrayList()
Dim intN As Integer = 0 Dim intI As Integer lbxBListed
.Items.Clear() ''选择书目列表清空 altBoo
kList.Clear() ''数组清空 int
N = clbBList.Items.Count For intI = 0 To intN - 1
If (clbBList.GetItemChecked(intI) = True) Then ''判断选择列表框中项
目是否勾选 altBookList.Add(clbBList.Items(intI))
''勾选项目添加到数组中 End If Next For intI = 0 To a
ltBookList.Count - 1 lbxBListed.Items.Add(altBookList(
intI)) ''勾选项目添加到列表框中 Next stuZhangsan.
BorrowBook(altBookList) ''以数组为参数调用BorrowBook方法
For intI = 0 To intN - 1 clbBList.SetItemChecked(intI
, False) ''清空选择列表框 Next lbxBListed.Ite
ms.Clear() ''清空书目列表框End Sub ⑼ 双击“借阅一本”按
钮,在“借阅一本”按钮Click事件过程中添加响应代码: Private Sub btnBorrowOne_Click(By
Val sender As System.Object, ByVal e As System.EventArgs) Handles
btnBorrowOne.Click lbxBListed.Items.Clear() lbxBList
ed.Items.Add(txtOneBName.Text) stuZhangsan.BorrowBook(txtO
neBName.Text) ''以字符串为参数调用BorrowBook方法 lbxBListed.I
tems.Clear() txtOneBName.Text = "" End Sub提示:学生类Student
中有两个BorrowBook方法,名字相同,但参数不同,一个是字符串,另一个是数组。这是方法的重载。6.2.4 可访问性在前面第三
章介绍过程和变量时,已经解释了修饰符Public和Private的用法。对于类中定义的变量、属性和方法(过程或函数),都可以使用不
同的修饰符规定各自的访问级别,从而实现类中数据访问的差异性和安全性。Visual Basic 2005中提供了Public、Pro
tected、Friend、Protected Friend、Private等多种访问修饰符,这里我们只介绍Public、Prot
ected和Private三种修饰符的含义。用Public修饰的变量、属性和方法(过程或函数),访问时没有限制,即不仅在类的内部可
以访问,而且从类的外部也可以访问。实际上,它们可看作是类对外公开的访问接口。需要注意的是,虽然用Public 修饰比较方便,但考虑
到信息的隐藏,建议大家慎重选择。用Protected修饰的变量、属性和方法(过程或函数),访问时有一定的限制,即不仅在类的内部可以
访问,而且继承该类的类从外部也可以访问。与Public相比,不同之处在于,对类的外部而言,只有继承该类的类才能进行访问。例如,在学
生类中用Protected修饰的变量、属性和方法,除了在学生类中和继承它的科协成员类与合唱团成员类中可以访问外,其它地方就不能再访
问它们了。用Private修饰的变量、属性和方法(过程或函数),访问时限制最多,即只能在类的内部可以访问,而从类的外部将禁止访问,
包括继承该类的类也不能进行访问。实际上,它们完全是私密的,不希望直接对外公开。6.3 构造函数和析构函数现在我们已经知道了如何定义
完整的类及其对象,并了解了方法重载。下面介绍类中两个特殊的方法:构造函数和析构函数。每个类中都有构造函数和析构函数,在相应对象建立
和删除的时候由系统自动调用,不能被显式调用。构造函数通常在对象建立时自动对对象进行初始化工作(例如为对象分配资源等),而析构函数则
恰恰相反,在对象删除时进行收尾工作(例如回收分配给对象的资源等)。如果没有明确定义,系统会有默认的构造函数和析构函数,但没有任何操
作。如果需要在对象创建、删除时进行一些操作,则需要在类中明确定义构造函数和析构函数。构造函数的名字必须是New,但可以在类中通过定
义不同参数形成多个构造函数,显然这是New的重载。析构函数的名字是Destruct,不带参数,而且只能有一个。例6.5 在例6.
1学生类中添加构造函数和析构函数,利用对话框显示执行过程。具体操作过程:⑴ 新建项目,选择“Windows应用程序”,把“名称”修
改为“学生类构造析构函数”,然后单击“确定”,并在解决方案资源管理器中将Form1.vb修改为frmStudent.vb。⑵ 将窗
体frmStudent的Text属性改为“学生类构造析构函数”。⑶ 添加学生类Student,具体操作过程同例6.1。⑷ 在“St
udent.vb”的代码编辑器中,往Student类中添加构造函数和析构函数的代码:Public Class Student ……
Public Sub New() ''构造函数,创建Student对象时显示提示信息 Me
ssageBox.Show("这是我定义的构造函数", "New") End Sub Public Sub De
struct() ''析构函数,删除Student对象时显示提示信息 MessageBox.Show(
"这是我定义的析构函数", "Destruct") End SubEnd Class⑸在“frmStudent.vb”
的代码编辑器中,往frmStudent类中添加生成Student类的对象stuZhangsan的代码:Public Class f
rmStudent Dim stuZhangsan As New Student ''新建Student类的对象stuZ
hangsanEnd Class⑹ 双击frmStudent窗体,在frmStudent窗体Load事件过程中添加响应代码:Pri
vate Sub frmStudent _Load(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles MyBase.LoadMessageBox.Show("这是程序的开始"
, "Form_load") stuZhangsan = Nothing ''
空引用,中断stuZhangsan和任何特定对象的关联 MessageBox.Show("这是程序的结束", "F
orm_load") End Sub 6.4 基本应用我们在使用Windows操作系统时,经常需要用鼠标或键盘点击程序窗体
上的“确定”或“取消”按钮。这实际就触发了一个Button_Click事件。其实Windows系统下大多数程序都是事件驱动的。如果
我们希望点击按钮后提交我们的选课信息,那么这时就需要我们自己编写一些代码来实现这件事,这些写在Button_Click里的代码就是
对应的事件处理程序。注意事件处理程序不能被显式调用,而是在满足某种条件时被触发执行。通常,系统已经定义好按钮控件Button的Cl
ick事件,用户需要做的就是编写相应的事件处理程序。但是我们也可以自己定义一些事件,同时规定好事件的触发条件,如同Button的C
lick事件一样,提供给用户使用。对于控件的事件及其使用,我们在前面的学习中已经有所了解,这里我们将以学生借书为例子解释自定义事件
及其使用。6.4.1 使用事件的步骤这里先说明通常使用事件的操作步骤:⑴ 使用Event在类、结构、模块和接口内部声明事件,例如C
lick。⑵ 使用 RaiseEvent 语句引发事件,例如指定为按钮Button的事件,就规定了只有按下按钮才会触发Click事
件。⑶ 编写该事件的事件处理程序,就是触发该事件时执行的代码,例如按下按钮后执行的Click事件代码。⑷ 使用 Handles 或
AddHandler 语句将所谓的事件处理程序与事件进行关联,这样才能使事件处理程序真正起作用,例如,按下按钮Button必然会
找到Button_Click中的代码执行。提示: 事件处理程序与事件关联的标准方法是使用 Handles和 WithEvents,
但动态启动事件的AddHandler 更加灵活。 两种关联方法可选择使用,但不能在一个事件中同时使用。6.4.2 事件的基本应用例
6.6 在例6.4的基础上练习自定义事件的使用。仍以学生借书为例,界面和功能不变,代码稍作修改,用事件实现学生借书总数超过10本
时的信息提示。具体改动如下:⑴ 在“Student.vb”的代码编辑器中,往Student类中添加事件BookToMax的声明代码
: Public Event BookToMax() ''添加事件声明⑵ 在“Student.vb”的
代码编辑器中,往Student类中添加引发事件BookToMax的代码,注意这里仅仅将其中的BorrowBook方法部分改写,代码
如下:Public Sub BorrowBook(ByRef altBNOlist As ArrayList) ''学
生一次借阅图书的书目列表 intBTotal = intBTotal + altBNOlist.Count If (
intBTotal < 11 And altBNOlist.Count <> 0) Then ''已借图书总数最多10本且添加所借书
目列表不为空 altBList.AddRange(altBNOlist) Messag
eBox.Show("借书登记操作成功!", "有效操作", MessageBoxButtons.OK) Else
intBTotal = intBTotal - altBNOlist.Count If
(altBNOlist.Count = 0) Then ''添加所借书目列表为空 Messag
eBox.Show("对不起,书名列表空白!", "无效操作", MessageBoxButtons.OK)
Else ''已借图书总数超过10本 RaiseEvent BookToMax()
''引发BookToMax事件 End If En
d IfEnd Sub⑶ 在“frmStudent.vb”的代码编辑器中,往Student类中添加过程InvalidTip的代码,
准备用于处理事件: Sub InvalidTip() ''定义事件处理程序 MessageBox.Sh
ow("对不起,借书总数已到最大值!", "无效操作", MessageBoxButtons.OK)End Sub⑷ 双击frmS
tudent窗体,在frmStudent窗体Load事件过程中添加响应代码:Private Sub frmStudent _Loa
d(ByVal sender As System.Object, ByVal e As System.EventArgs) Han
dles MyBase.Load''用AddHandler将事件BookToMax和事件处理程序InvalidTip动态连接
AddHandler stuZhangsan.BookToMax, AddressOf InvalidTip End S
ub 6.5 继承正如前面举例提到的,我们可以通过继承已有的系统提供的类或自己编写好的类来得到新的类,这使我们既可很快写出程序,又
能保证程序的质量。提供出来供继承的类称为基类,继承其它类的类则称为派生类。派生类可直接获得基类的属性、方法和事件,同时也可以进行扩
展或重写。Visual Basic中的所有对象都可看作是从共同基类System..Object派生出来的。在前面的例子中,学生类是
基类,科协成员类则是派生类。在Visual Basic中,实现继承的常见方法是将Inherit语句作为派生类的第一条语句,表示继承
基类中非Private声明的所有成员。具体用法是:Inherits 基类名称需要注意的是,该语句必须是类的第一条语句,而且基类名
字只能是一个,因为Visual Basic只支持单一继承。例6.7 考虑到学校内部有很多学生社团,例如学生科协,假定科协成员喜欢
上网。我们让科协成员类直接继承学生类,同时在科协成员类中添加Play方法,指定娱乐方式是上网。具体操作过程:⑴ 新建项目,选择“W
indows应用程序”,把“名称”修改为“科协成员继承学生”,然后单击“确定”, 并在解决方案资源管理器中将Form1.vb修改为
frmStudent.vb。⑵ 将窗体frmStudent的Text属性改为“科协成员继承学生”。⑶ 添加学生类Student,包
括基本信息和方法InputStuInfo和OutputStuInfo,具体操作过程同例6.3。⑷ 在“Student.vb”的代码
编辑器中,添加定义科协成员类SCMember的代码:Public Class SCMember
''定义科协成员类 Inherits Student
''从Student类派生 Public Sub Play() ''增加方法
Play Process.Start("http://www.snnu.edu.cn") End SubEnd
Class 提示:通过Process 组件可以启动、停止应用程序(进程),也可以控制和监视正在运行的应用程序。Process.S
tart("http://www.snnu.edu.cn")运行的结果是:启动本地主机的默认浏览器,访问http://www.sn
nu.edu.cn Web服务。⑸在“frmStudent.vb”的代码编辑器中,往frmStudent类中添加生成SCMembe
r类的对象scmLisi的代码:Public Class frmStudent Dim scmLisi As New Stud
ent.SCMember ''新建SCMember类的对象scmLisiEnd Class⑹ 双击frmStudent窗体
,在frmStudent窗体Load事件过程中添加响应代码:Private Sub frmStudent_Load(ByVal s
ender As System.Object, ByVal e As System.EventArgs) Handles MyBa
se.LoadscmLisi.InputStuInfo()scmLisi.OutputStuInfo()scmLisi.Play(
)End Sub 提示:scmLisi是科协成员类对象,但继承了父类Student的方法InputStuInfo和OutputSt
uInfo,而且添加了新方法Play。6.6 多态前面已经举例解释了多态的含义,多态就是类中方法名字相同但实现的功能却不同。具体来
说,就是在基类中定义方法,同时在派生类中重写该方法,从而实现不同的功能效果,而且调用时只需要知道是派生类的对象即可,并不需要指定是
哪个具体类的对象。这就带来了很大的方便,尤其是以后类的维护和功能的维护。学生类中定义了娱乐Play方法,在科协成员类和合唱团成员类
中也都继承实现各自的Play方法,分别实现上网和听歌曲的娱乐功能。我们在调用娱乐Play方法时,只要知道是学生类派生的对象就可以了
,至于到底是科协成员对象还是合唱团成员对象,我们就不用操心了,多态机制会自动帮我们做出正确的选择判断。前面的例子是Visual B
asic中基于继承实现的多态,当然也可实现更为抽象的基于接口实现的多态,而且多态概念也涉及到属性。这里我们就不再进一步讨论了。多态
的具体实现是:⑴ 在基类中用Overridable修饰方法,表示基类中的该方法可以在派生类中被重写,即在基类中声明可以在子类中重新
定义该方法;⑵ 在派生类中用Overrides修饰该方法,表示在派生类中重写基类里已经用Overridable修饰的方法,即在派生
类中重新定义基类里用Overridable修饰的方法的功能。例6.8 考虑到每个学生有自己的娱乐方式,在例6.1学生类中添加空方
法Play。假定学生社团有科协和合唱团,科协成员喜欢上网,合唱团成员喜欢听歌曲。我们让科协成员类和合唱团成员类直接继承学生类,同时
在科协成员类中添加Play方法,指定娱乐方式是上网,在合唱团成员类中添加Play方法,指定娱乐方式是听歌曲。这样当学生是科协成员时
自动打开浏览器上网,当学生是合唱团成员时自动打开播放器听歌曲。具体操作过程:⑴ 新建项目,选择“Windows应用程序”,把“名称
”修改为“科协合唱团多态”,然后单击“确定”, 并在解决方案资源管理器中将Form1.vb修改为frmStudent.vb。⑵ 将
窗体frmStudent的Text属性改为“科协合唱团多态”。⑶ 在例6.1学生类中Student添加空方法Play,并在“Stu
dent.vb”代码编辑器中再增加科协成员类和合唱团成员类两个类,它们直接继承学生类,代码如下:Public Overridabl
e Sub play() ''添加空方法PlayEnd SubPublic Class SCMember
''定义科协成员类 Inherits Student
''从Sudent类派生 Public Overrides Sub Play()
''增加方法Play Process.Start("http://www.snnu.edu.cn") ''打开浏览
器,访问Web主页操作 End SubEnd ClassPublic Class GCMember
''定义合唱团成员类 Inherits Student
''从Sudent类派生 Public Overrides Sub Play()
''增加方法Play Process.Start("Auld Lang Syno(友谊地久天长).mp3") ''播
放mp3音乐 End SubEnd Class⑷ 为窗体添加1个Label控件,将Text改为“学生社团:”;添加1个Lis
tBox控件,将Name改为“lbxMember”, 并在Items字符串集合编辑器中依次输入科协成员和合唱团成员,每行一个;添加1个Button控件,将Name改为“btnPlay”,Text改为“娱乐”。⑸ 在“frmStudent.vb”的代码编辑器中,添加变量声明和定义的代码:Public Class frmStudentDim stuZhangsan As Student Dim ObjSCMember As New Student.SCMember ''新建科协成员类的对象ObjSCMember Dim ObjGCMember As New Student.GCMember ''新建合唱团成员类的对象ObjGCMemberEnd Class⑹ 双击frmStudent窗体,在frmStudent窗体Load事件过程中添加响应代码:Private Sub frmStudent_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.LoadstuZhangsan = ObjSCMember ''stuZhangsan指向ObjSCMember对象End Sub ⑺ 双击ListBox控件,在ListBox控件SelectedIndexChanged事件过程中添加响应代码: Private Sub lbxMember_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lbxMember.SelectedIndexChangedSelect Case lbxMember.SelectedItem Case "科协成员" stuZhangsan = ObjSCMember ''stuZhangsan指向ObjSCMember对象 Case "合唱团成员" stuZhangsan = ObjGCMember ''stuZhangsan指向ObjGCMember对象 End SelectEnd Sub⑻ 双击“娱乐”按钮,在“娱乐”按钮Click事件过程中添加响应代码:Private Sub btnPlay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPlay.ClickstuZhangsan.play() ''根据stuZhangsan对象的当前具体类型,执行相应类的play方法End Sub 注意:这里 Dim stuZhangsan As Student只是声明,并不是真正的对象,在程序执行过程中stuZhangsan将指向实际的对象,根据执行对象的不同而选择不同的行为。
献花(0)
+1
(本文系大高老师原创)