VB.Net中文教程(5)程序多重定义

程序|教程|中文

1. 程序成员的多重定义

「程序多重定义」(Function Overloading)又称为「程序重复定义」。它让对象更具弹性﹐能处理多样化之讯息。这观念源于日常生活经验。例如﹐我们常说﹕
◎ 猫 玩 绣球
◎ 猫 玩 老鼠
◎ 猫 玩 鱼

猫玩绣球与玩老鼠之玩法不尽相同。但何以使用同一动词──「玩」呢﹖也许人们认为其目的是一致的﹕猫获得快乐。上述的「猫」为类别﹐而某只猫是对象。例如﹕加菲猫是对象﹐它可接受讯息──

其中﹐「玩」代表着动作和过程﹐而绣球、老鼠及鱼则是「玩」之对象。回想﹐在程序中﹐「程序」代表一项动作及过程﹐而「自变量值」则为程序之处理对象。因之﹐上图可表示为──

图1、 play()之多重定义

OOP 程序设计之理想为﹕让程序之写法与人们日常生活经验吻合﹐于是设计个Play()程序﹐让它能接受不同型态之资料做为处理对象。上述Play()已具「多重定义」﹐其特点是──
1. 程序名称相同﹐例如﹕Play()。
2. 自变量不同﹐例如﹕老鼠和鱼。

因猫玩绣球和玩老鼠的方法略有不同﹐例如老鼠是活的而绣球是死的﹐其玩的过程亦不尽相同。为了表示动作与过程之不同﹐Play()程序内之指令也有所不同。例如﹕

写VB程序时﹐其格式必须是──

Class Cat
Public Overloads Sub Play(绣球)
指令
.......
End Sub
Public Overloads Sub Play(老鼠)
指令
.......
End Sub
Public Overloads Sub Play(鱼)
指令
.......
End Sub
End Class

这就是「程序成员多重定义」了。Cat 类别含有三种Play()之定义﹐其自变量不同而且内部指令亦不相同。于是Play()程序能接受不同之自变量﹐并执行不同之指令﹐使得Play()具弹性了。请看个程序──

'ex01.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-------------------------------------------------------
Class Example
Public Overloads Sub Display()
MessageBox.Show("****")
End Sub
Public Overloads Sub Display(ByVal r As Integer)
MessageBox.Show(str(r))
End Sub
Public Overloads Sub Display(ByVal f As Double)
MessageBox.Show(str(f + 2))
End Sub
Public Overloads Sub Display(ByVal s As String)
MessageBox.Show(s)
End Sub
End Class
'--------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
........
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim a As New Example()
a.Display()
a.Display("Taiwan")
a.Display(80)
a.Display(100.5)
End Sub
End Class

此程序输出如下﹕ ****
Taiwan
80
102.5

这Example类别比较特殊﹐没有资料成员﹔但含有一个程序成员叫Display() 。而Display()有 4个不同之版本(定义)﹐可任君(计算机)挑选。计算机藉比对自变量来挑选「最相配」之Display()程序。
例如﹕计算机执行到指令──
a.Display("Taiwan")

由于自变量── "Taiwan"是字符串﹐其型态应配上String﹐所以计算机挑选并且执行第 4个程序── Display( ByVal s As String ) 。同理﹐当计算机执行到指令──
a.Display(100.5)

由于自变量──100.5之型态为Double﹐所以计算机选上并执行第 3个Display()程序── Display(ByVal f As Double )。同一程序名称但有数个不同之定义﹐各有不同之自变量及内部指令﹐此种现象就是「程序的多重定义」。

请再看个例子──

'ex02.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'--------------------------------------------------
Class Sum
Private s As Integer
Public Overloads Sub Add()
s = 3 + 5
End Sub
Public Overloads Sub Add(ByVal x As Integer)
s = x + 5
End Sub
Public Overloads Sub Add(ByVal x As Integer, ByVal y As Integer)
s = x + y
End Sub
Public Sub Show()
MessageBox.Show("Sum = " + str(s))
End Sub
End Class
'---------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
........
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim a As New Sum()
a.Add()
a.Show()
a.Add(80)
a.Show()
Dim b As New Sum()
b.Add(100, 27)
b.Show()
End Sub
End Class

此程序输出如下﹕ Sum = 8
Sum = 85
Sum = 127

当计算机执行到指令── b.Add( 100, 27 ),由于有两个自变量﹐且型态皆为Integer﹔计算机就选上并执行第三个Add() 程序。此时计算机把100传给x﹐而27传给y。这多重定义之观念﹐也常用于建构者程序上。例如﹕

'ex03.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'---------------------------------------------------
Class Rectangle
Private height As Integer, Width As Integer
Public Overloads Sub New()
height = 0
width = 0
End Sub
Public Overloads Sub New(ByVal k As Integer)
height = k
width = k
End Sub
Public Overloads Sub New(ByVal h As Integer, ByVal w As Integer)
height = h
width = w
End Sub
Public Sub ShowArea()
MessageBox.Show("Area = " + str(height * width))
End Sub
End Class
'---------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
.......
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim r1 As New Rectangle()
Dim r2 As New Rectangle(8)
Dim r3 As New Rectangle(5, 6)
r1.ShowArea()
r2.ShowArea()
r3.ShowArea()
End Sub
End Class

此程序输出﹕ Area = 0
Area = 64
Area = 30

宣告对象时﹐若未给予自变量值﹐计算机呼叫New()﹔若给一个自变量值── 8﹐就呼叫 New(ByVal k As Integer) ﹔若给二个自变量值──5 及 6﹐则呼叫New(ByVal h As Integer, ByVal w As Integer)。请再看一个例子:

'ex04.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-------------------------------------------------------------------------------------------------
Class Rectangle
Private height As Integer, Width As Integer
Public Sub New(ByVal h As Integer, ByVal w As Integer)
height = h
width = w
End Sub
Public Function Area() As Integer
Area = height * width
End Function
Public Overloads Function CompareWith(ByVal a As Integer) As Integer
Dim d As Integer
d = Area() - a
If d <> 0 Then
CompareWith = 1
Else
CompareWith = 0
End If
End Function
Public Overloads Function CompareWith(ByVal r As Rectangle) As Integer
Dim d As Integer
d = Area() - r.Area()
If d <> 0 Then
d = 1
End If
CompareWith = d
End Function
Public Overloads Function CompareWith( ByVal x As Rectangle, ByVal
y As Rectangle) As Integer
Dim d As Integer
d = x.Area() - y.Area()
If d <> 0 Then
d = 1
End If
CompareWith = d
End Function
End Class
'----------------------------------------------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
........
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim r1 As New Rectangle(10, 50)
Dim r2 As New Rectangle(20, 25)
If r1.CompareWith(400) = 0 Then
MessageBox.Show("EQUAL")
Else
MessageBox.Show("NOT EQUAL")
End If
If r1.CompareWith(r2) = 0 Then
MessageBox.Show("EQUAL")
Else
MessageBox.Show("NOT EQUAL")
End If
If r1.CompareWith(r1, r2) = 0 Then
MessageBox.Show("EQUAL")
Else
MessageBox.Show("NOT EQUAL")
End If
End Sub
End Class

此程序输出﹕ NOT EQUAL
EQUAL
EQUAL

如此﹐CompareWith()程序就有三种用途了﹔如果您想增加其它用途﹐可尽情地再定义它。r1.CompareWith(400)呼叫第1个CompareWith(),比比看r1面积是否大于400;r1.ComapreWith(r2) 呼叫第2个CompareWith(),比比看r1面积是否大于r2的面积;r1.ComapreWith(r1, r2) 比比看r1面积是否大于r2的面积。如果没有使用多重定义方法,这三个程序名称不能相同。例如﹕上述程序可改写为──

'ex05.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-------------------------------------------------------------------------------------------
Class Rectangle
Private height As Integer, Width As Integer
Public Sub New(ByVal h As Integer, ByVal w As Integer)
height = h
width = w
End Sub
Public Function Area() As Integer
Area = height * width
End Function
Public Function CompareWithInteger(ByVal a As Integer) As Integer
Dim d As Integer
d = Area() - a
If d <> 0 Then
d = 1
End If
CompareWithInteger = d
End Function
Public Function CompareWithRectangle(ByVal r As Rectangle) As Integer
Dim d As Integer
d = Area() - r.Area()
If d <> 0 Then
d = 1
End If
CompareWithRectangle = d
End Function
Public Function CompareTwoRectangle( ByVal x As Rectangle, ByVal
y As Rectangle) As Integer
Dim d As Integer
d = x.Area() - y.Area()
If d <> 0 Then
d = 1
End If
CompareTwoRectangle = d
End Function
End Class
'---------------------------------------------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
........
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim r1 As New Rectangle(10, 50)
Dim r2 As New Rectangle(20, 25)
If r1.CompareWithInteger(400) = 0 Then
MessageBox.Show("ggg EQUAL")
Else
MessageBox.Show("NOT EQUAL")
End If
If r1.CompareWithRectangle(r2) = 0 Then
MessageBox.Show("EQUAL")
Else
MessageBox.Show("NOT EQUAL")
End If
If r1.CompareTwoRectangle(r1, r2) = 0 Then
MessageBox.Show("EQUAL")
Else
MessageBox.Show("NOT EQUAL")
End If
End Sub
End Class

此程序输出﹕
NOT EQUAL
EQUAL
EQUAL

由于各程序名称不相同,您就得记忆各程序之名字﹐徒增记忆负担而且易于犯错﹐并不合乎人们生活习惯。因之﹐VB的多重定义观念﹐能增加程序之弹性及亲切感。
程序多重定义情形并不限于单一类别之内,也可以发生于父子类别之间。例如:

'ex06.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'------------------------------------------------------------------------------------------
Public Class Person
Private name As String
Private age As Integer
Public Sub New()
End Sub
Public Sub SetValue(ByVal na As String, ByVal a As Integer)
name = na
age = a
End Sub
Public Function birthDay() As Integer
birthDay = 2001 - age
End Function
Public Sub Display()
Messagebox.Show("Name: " + name + " Age: " + str(age))
End Sub
End Class

Public Class Teacher
Inherits Person

Private salary As Decimal
Public Overloads Sub SetValue( ByVal na As String, ByVal a As Integer, ByVal
sa As Decimal)
SetValue(na, a)
salary = sa
End Sub
Public Sub pr()
MyBase.Display()
Messagebox.Show("Salary: " + str(salary))
End Sub
End Class

Public Class Student
Inherits Person

Private student_number As Integer
Public Overloads Sub SetValue( ByVal na As String, ByVal a As Integer, ByVal
no As Integer)
SetValue(na, a)
student_number = no
End Sub
Public Sub pr()
MyBase.Display()
Messagebox.Show("StudNo: " + str(student_number))
End Sub
End Class
'-----------------------------------------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
........
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim x As New Person()
x.SetValue("Alvin", 32)
Dim y As New Student()
y.SetValue("Tom", 36, 11138)
x.Display()
y.pr()
End Sub
End Class

Teacher类别从Person继承了SetValue() ──
SetValue(ByVal na As String, ByVal a As Integer)

自己又重复定义一个新的SetValue()程序──
SetValue(ByVal na As String, ByVal a As Integer, ByVal no As Integer)

共有两个SetValue()可用。指令x.SetValue("Alvin", 32)呼叫第1个SetValue();指令y.SetValue("Tom", 36, 11138)呼叫第1个SetValue()。
兹在扩充一个子类别如下:

'ex07.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'------------------------------------------------------------------------------------------
Public Class Person
Private name As String
Private age As Integer
Public Sub New()
End Sub
Public Sub SetValue(ByVal na As String, ByVal a As Integer)
name = na
age = a
End Sub
Public Function birthDay() As Integer
birthDay = 2001 - age
End Function
Public Overridable Sub Display()
Messagebox.Show("Name: " + name + " Age: " + str(age))
End Sub
End Class

Public Class Teacher
Inherits Person

Private salary As Decimal
Public Overloads Sub SetValue( ByVal na As String, ByVal a As Integer, ByVal
sa As Decimal)
SetValue(na, a)
salary = sa
End Sub
Public Overrides Sub Display()
MyBase.Display()
Messagebox.Show("Salary: " + str(salary))
End Sub
End Class

Public Class Student
Inherits Person

Private student_number As Integer
Public Overloads Sub SetValue( ByVal na As String, ByVal a As Integer, ByVal
no As Integer)
SetValue(na, a)
student_number = no
End Sub
Public Overrides Sub Display()
MyBase.Display()
Messagebox.Show("StudNo: " + str(student_number))
End Sub
End Class
'-----------------------------------------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
........
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim x As New Person()
x.SetValue("Alvin", 32)
Dim y As New Student()
y.SetValue("Tom", 36, 11138)
x.Display()
y.Display()
End Sub
End Class

此程序输出﹕
Name: Alvin Age: 32
Name: Tom Age: 36
StudNo: 11138

此时﹐Student 类别含有两个SetValue()程序,一个是从Person类别继承而来,另一个是自行定义的。如果上述Form1_Click()内的指令更改如下:

Dim y As New Student()
y.SetValue("Tom", 36, 5000.25) 'Error!
y.Display()

虽然SetValue("Tom", 36, 5000.25)合乎Teacher的SetValue()程序的参数,但是Student并非Person的子类别,没有继承Student的SetValue(),所以错了。n

时间: 2016-02-06

VB.Net中文教程(5)程序多重定义的相关文章

VB.Net中文教程(4) 类别继承(Inheritance)关系

继承|教程|中文 1. 类别之继承 类别之间﹐有些互为独立﹐有些具有密切关系.兹介绍类别间常见的关系──「父子」关系﹔由于儿女常继承父母之生理或心理特征﹐所以又称此关系为「继承」(Inheritance) 关系.类别间之密切关系﹐把相关的类别组织起来﹐并且组织程序内之对象.若程序内之对象毫无组织﹔呈现一片散沙﹐就不是好程序.完美之VB程序﹐必须重视类别间之关系﹐对象是有组织的. 如果 A类别「继承」 B类别﹐则称 A为「子类别」(Subclass)﹐也称B 为「父类别」(Superclass)﹐

VB.Net中文教程(8) 对象(Object)基本概念

object|对象|概念|教程|中文 主题: 对象(Object)基本概念 ???????????? 内容 ????????????v 1. 何谓「对象导向」? v 2. 认识与寻找对象v 3. 对象之分类与组织v 4. 类别之设计 v 5. 对象之行为v 6. 讯息与运算v 7. 类别之定义 v 8. 着手写 VB程序 大地运转.花开花谢.及枫叶飘零 ...... 是自然界对象之行为.对象行为交互作用﹐造成多采多姿的大自然.软件的对象是自然界对象的抽象表示,软件就逼真地表达自然界的实际景象﹐于

VB.Net中文教程(12) 共享成员(Shared Member)

教程|中文 主题: 共享成员(Shared Member) ?????? 内容 ??????v 1. 共享资料成员v 2. 共享程序成员 您已经习惯像 New Employee("Tom", 25)这样的指令了,看到这个指令可以想向它是:Employee.New("Tom", 25),于是不难想象到,原来类别也是对象!这个类别对象(Class Object)接到New()讯息时,就去诞生一个对象,原来类别对象就是妈妈对象(Meta Object)!妈妈是小孩共有的,

VB.Net中文教程(2) Composite样式

教程|中文 1. 从Whole-part关系谈起 回想传统的软件师﹐常甚专注于撰写程序(procedure) 来处理某些资料(data)﹐较少关心软件的整体结构(architecture).在现在的OO软件中﹐把资料及其相关的程序结合在一起﹐封装(encapsulate) 在对象之中.软件师在使用对象时﹐通常把对象视为黑箱(black-box) ﹐不会关心于对象内部之细节﹔因之能专注于对象之间的关系.软件师的主要工作﹐就是在于建立对象之间的互助合作(collaboration) 关系﹐为对象安排

VB.Net中文教程(7) Me参考值

参考|教程|中文 1. 使用Me参考值1.1 认识Me参考值 类别之程序成员(Procedure Member) 各含一个Me参考变量﹐它永远参考到「目前对象」(Current Object).目前对象就是正接受并处理讯息之对象.例如﹐ 'ex01.basImports System.ComponentModelImports System.DrawingImports System.WinForms'-----------------------------------------------

VB.Net中文教程(9) 重新定义(Overriding)程序

程序|教程|中文 主题: 重新定义(Overriding)程序 ?????????? 内容 ??????????v 1. 重新定义程序 1. 重新定义(Override)程序 在应用上﹐常见如下之情况﹕子类别从父类别继承之程序﹐并不合乎子类别之需要.此时可设计新程序取代之. 图1.程序成员之重新定义 例如﹐SalesPerson类别含有Bonus()程序﹔SalesManager由 SalesPerson继承而得Bonus()程序.Bonus()能计算销售人员之红利.然而﹐一般销售员与销售经理之

VB.Net中文教程(11) Prototype样式

教程|中文 主题: Prototype样式副题: 多形性.接口(Interface) ????????? 内容 ?????????v 1. 样式v 2. 对象之原型(object prototype)v 3. 以VB落实Prototype样式v 4. Prototype样式之应用----- 组件之设计与组装 1. 样式 Erich Gamma 等人的名著──"Design Patterns: Elements of Reusable Object-Oriented Software"

VB.Net中文教程(13) Whole-Part关系

教程|中文 主题: Whole-Part关系 ?????????? 内容 ??????????v 1. 对象Whole-Part关系v 2. 组合/部分关系v 3. 包含者/内容关系v 4. 集合/成员关系 1. 对象Whole-Part关系 类别继承(Class inheritance)和对象组合(Object composition)是软件再使用(Reuse)的两大法宝.类别继承就是建立父.子类别之关系﹔例如﹐「学生」可分为「大学生」.「中学生」和「小学生」三类别﹐其继承关系图标如下﹕ 图1

VB.Net中文教程(1) 类别与封装性

封装|教程|中文 1. 类别的「程序成员」(Procedure Member) 类别 (Class)之任务是把资料(Data)和程序(Procedure)组织并封装起来.类别告诉计算机﹕「其对象应含有那些资料.应含有那些程序裨处理外界传来之讯息」.类别须详细说明它的资料及程序﹐我们称此资料是类别之「资料成员」(Data Member) ﹔而称此程序是类别之「程序成员」(Procedure Member).有关类别内容之叙述﹐就是所谓的类别定义(Class Definition).类别定义之格式为