首页 > 编程 > .NET > 正文

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

2024-07-10 13:01:17
字体:
来源:转载
供稿:网友
  • 本文来源于网页设计爱好者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

    发表评论 共有条评论
    用户名: 密码:
    验证码: 匿名发表