本文来源于网页设计爱好者web开发社区http://www.html.org.cn收集整理,欢迎访问。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