本文来源于网页设计爱好者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