本文來源于網頁設計愛好者web開發社區http://www.html.org.cn收集整理,歡迎訪問。1. 程序成員的多重定義
「程序多重定義」(function overloading)又稱為「程序重復定義」。它讓對象更具彈性﹐能處理多樣化之訊息。這觀念源于日常生活經驗。例如﹐我們常說﹕
◎ 貓 玩 繡球
◎ 貓 玩 老鼠
◎ 貓 玩 魚
貓玩繡球與玩老鼠之玩法不盡相同。但何以使用同一動詞──「玩」呢﹖也許人們認為其目的是一致的﹕貓獲得快樂。上述的「貓」為類別﹐而某只貓是對象。例如﹕加菲貓是對象﹐它可接受訊息──
其中﹐「玩」代表著動作和過程﹐而繡球、老鼠及魚則是「玩」之對象?;叵氅o在程序中﹐「程序」代表一項動作及過程﹐而「自變量值」則為程序之處理對象。因之﹐上圖可表示為──
圖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