分享
 
 
 

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

王朝vb·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

请注意 ......

著作权所有人:物泽计算机事业股份有限公司、

MISOO对象技术顾问团队、对象导向杂志作者、等。

u本文件摘自 对象导向杂志、精通对象观念与技术等书籍著作。

u本文件仅供您的参阅,请遵守著作权法,不得做其它商业用途。

主题: Me参考值

?????? 内容 ??????

v 1. 活用Me参考值

1.1认识Me参考值

1.2程序传回Me参考值

v 2. 认深入了解Me参考值

1. 使用Me参考值

1.1 认识Me参考值

类别之程序成员(Procedure Member) 各含一个Me参考变量﹐它永远参考到「目前对象」(Current Object)。目前对象就是正接受并处理讯息之对象。例如﹐

'ex01.bas

Imports System.ComponentModel

Imports System.Drawing

Imports System.WinForms

'------------------------------------------------------------------------------

Public Class Fee

Private amount As Decimal

Public Sub New(ByVal amt As Decimal)

Me.amount = amt

End Sub

Public Sub disp()

MessageBox.Show("Amount is " + str( Me.amount ))

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 Fee(100)

Dim b As New Fee(80)

a.disp()

b.disp()

End Sub

End Class

此程序输出如下﹕Amount is 100

Amount is 80

a 和 b是Fee类别之对象。当计算机执行指令──

a.disp()

a 就是目前对象﹐disp()程序里的Me正参考到对象a。

也可看成:

图1、 Me参考值与目前对象

请注意﹕Me参考到对象a﹐也就是Me与a皆参考到同一个对象。

当计算机执行另一指令── b.disp()时,b 即为目前对象﹐而disp()程序之Me参考正指向对象 b。

由于Me正参考到对象b﹐所以Me与b参考到同一个对象。写程序时﹐宜充分利用Me参考。

1.2 程序传回Me参考值

在应用上﹐程序常传回Me参考值﹐可创造奇妙的效果﹐这种效果也是VB的重要特色。希望您能仔细了解Me指针之使用场合﹐能让您写出完美的OOP程序来﹗现在﹐请看个熟悉的程序──

'ex02.bas

Imports System.ComponentModel

Imports System.Drawing

Imports System.WinForms

'------------------------------------------------------------------------------

Public Class Money

Private balance As Decimal

Public Sub New(ByVal amount As Decimal)

balance = amount

End Sub

Public Sub add(ByVal saving As Decimal)

balance = balance + saving

End Sub

Public Sub Display()

MessageBox.Show("Balance is " + str(balance))

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 orange As New Money(100)

orange.add(300)

orange.add(80)

orange.Display()

End Sub

End Class

此程序输出如下﹕Balance is 480

Money 类别的 balance资料﹐记录存款余额。main()内之对象orange接受两讯息──add(300)及add(80) ﹐欲存入两项金额。

指令── orange.add(300)

orange.add(80)

表示﹕先存入 300元再存入80元﹐有先后次序。若上述图形改为──

则更具次序感。于是﹐上述指令相当于──

这种效果﹐不太陌生吧﹗回忆小学时,班长喊着:「起立、敬礼、坐下」,您不是连续接受到三个讯息吗?渐渐地﹐您已能设计出像日常生活这般亲切之对象了。不过﹐俗语说﹕「万丈高楼平地起」﹐还是必须先对Me参考有充分了解才行﹗请看个程序──

'ex03.bas

Imports System.ComponentModel

Imports System.Drawing

Imports System.WinForms

'-----------------------------------------------------------------------------------

Public Class Money

Private balance As Decimal

Public Sub New(ByVal amount As Decimal)

balance = amount

End Sub

Public Function add(ByVal saving As Decimal) As Money

balance = balance + saving

add = Me

End Function

Public Sub Display()

MessageBox.Show("Balance is " + str(balance))

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 orange As New Money(100)

orange.add(300).add(80)

orange.Display()

End Sub

End Class

此程序输出如下﹕Balance is 480

由于Me永远参考到目前对象﹐此刻Me正参考到对象orange。

图2、 程序传回目前对象之参考值

oragne对象就是Me所指之对象﹐也可以说Me与orange皆参考到同一个对象。指令──

add = Me

传回目前对象之参考值──即orange对象之参考。add() 程序之定义──

于是add()把目前对象之参考值Me传回Form1_Click()。此刻﹐orange.add(300)之值也是参考值,与orange参考到同一个对象。

于是,Form1_Click()程序之指令──

成为orange对象之别名了。

原来的指令── orange.add(300).add(80)

相当于── orange.add(80)

不过﹐此时orange对象之 balance变量值为400元﹐而非原来的100元了。此orange再接受讯息── add(80)﹐其 balance值增加为480 元。orange接到第 2个讯息── add(80)时﹐计算机再执行add() 程序﹐其再度传回orange的参考值﹐使得整个指令──

又成为orange之别名。因之﹐亦能把disp()讯息接于其后﹐如下﹕

'ex04.bas

Imports System.ComponentModel

Imports System.Drawing

Imports System.WinForms

'------------------------------------------------------------------------------------

Public Class Money

Private balance As Decimal

Public Sub New(ByVal amount As Decimal)

balance = amount

End Sub

Public Function add(ByVal saving As Decimal) As Money

balance = balance + saving

add = Me

End Function

Public Sub Display()

MessageBox.Show("Balance is " + str(balance))

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 orange As New Money(100)

orange.add(300).add(80).Display()

End Sub

End Class

此程序输出如下﹕Balance is 480

orange对象接到第 1个讯息──add(300)﹐计算机就执行add()程序,执行到结尾指令﹐传回Me(即orange对象)参考值。此时Form1_Click()的orange.add(300)就是orange对象之参考值﹐亦即orange.add() 是orange对象之别名﹔则orange和 orange.add(300)重合在一起﹐代表着同一对象──原来的orange对象。

接下来﹐第 2个讯息──add(80)传给orange.add(300) ﹐相当于传给orange对象。再度执行到 add()里的的add = Me指令时﹐又令orange.add(300).add(80) 成为 orange.add(300)之别名﹐即orange之别名﹔于是﹐三者代表同一对象──原来的orange对象。

接下来﹐第3个讯息──Display传给orange.add(300).add(80) ﹐相当于传给orange对象。

于是输出orange对象内的balance值。

以程序传回Me参考值之技巧将应用于许多方面。为了更了解这种方法﹐请看个特殊情形── 程序传回新对象之参考值。此对象不是目前对象,但内容是从目前对象拷贝而来。这不同于传回Me参考值的情形﹐两种用法常令人搞混﹗现在﹐把程序改为──

'ex05.bas

Imports System.ComponentModel

Imports System.Drawing

Imports System.WinForms

'------------------------------------------------------------------------------------

Public Class Money

Private balance As Decimal

Public Sub New(ByVal amount As Decimal)

balance = amount

End Sub

Public Function add(ByVal saving As Decimal) As Money

Dim newobj As Money

newobj = New Money( balance + saving )

add = newobj

End Function

Public Sub Display()

MessageBox.Show("Balance is " + str(balance))

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 orange As New Money(100)

orange.add(300).add(80).Display()

End Sub

End Class

此程序输出如下﹕Balance is 480

当orange对象接到第 1个讯息──add(300)﹐计算机就执行add()程序﹐诞生一个Money类别的新对象﹐把目前对象内容(即orange对象之值)拷贝一份给Form1_Click()。这份拷贝就是orange.add(300)之值。

orange.add(300) 即为拷贝回来的那份对象﹐并非原来的orange对象。当讯息──add(80)传给orange.add(300)所代表的对象时﹐计算机就执行add()函数﹐此时目前对象是orange.add(300) 而非原来的orange。执行时﹐又把目前对象──orange.add(300)内容拷贝一份给新诞生的对象,传回给Form1_Click()程序﹐这份拷贝就是orange.add(300).add(80) 之值。

由于每回执行add()就产生一份新对象(虽然内容相同﹐但占不同的内存空间)﹐其后的讯息皆传给add()所诞生之新对象﹐而非orange对象,所以这些讯息皆不影响原来orange对象之内容。

请注意﹕Display()并未传回对象之参考值﹐则Display()讯息之后不得再接其它讯息了。所以﹐如果Form1_Click()程序改写如下,那就错了──

Protected Sub Form1_Click( ByVal sender As Object,

ByVal e As System.EventArgs)

Dim orange As New Money(100)

orange.add(300).Display().add(80) 'Error!

End Sub

End Class

因Display()不传回对象之参考值﹐则指令──

其后之讯息──add(80) 是错的。如何改正呢﹖很简单﹐只需叫Display()程序传回 Me(目前对象之参考值)或新对象之参考值即可﹐如下﹕

'ex06.bas

Imports System.ComponentModel

Imports System.Drawing

Imports System.WinForms

'-------------------------------------------------------------------------------------

Public Class Money

Private balance As Decimal

Public Sub New(ByVal amount As Decimal)

balance = amount

End Sub

Public Function add(ByVal saving As Decimal) As Money

Dim newobj As Money

newobj = New Money( balance + saving )

add = newobj

End Function

Public Function Display() As Money

MessageBox.Show("Balance is " + str(balance))

Display = Me

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 orange As New Money(100)

orange.Display().add(300).Display().add(80).Display()

End Sub

End Class

此程序输出﹕

Balance is 100

Balance is 400

Balance is 480

此程序中﹐orange先接受Display()讯息﹐印出存款额﹔再接受add(300)讯息﹐使存款额提高 300元﹐再接受Display()讯息﹐依序下去。Display()传回来目前对象orange之参考值,add()则传回新诞生对象之参考值。

2. 深入了解Me参考

VB在编译时﹐会自动为程序成员产生Me参考变量﹐并令Me固定参考到目前对象(Current Object)。于此将细谈VB如何产生Me参考变量﹐让您更能深刻了解Me参考变量的特性和角色。首先﹐VB在编译程序成员时﹐会暗中偷加上1 个参考参数──Me﹐成为该程序成员的第1 个参数。例如﹕

Class Person

Private name As String

Priavte age As Integer

Public Sun New(ByVal na As String, ByVal a As Integer)

name = na

age = a

End Sub

Public Sub Display()

Messagebox.Show( name + ", " + str( age ) )

End Sub

End Class

在编译此程序时﹐VB会将偷加上Me参考变量如下﹕

Class Person

Private name As String

Priavte age As Integer

Public Sun New( ByVal Me As Person, ByVal na As String,

ByVal a As Integer)

Me.name = na

Me.age = a

End Sub

Public Sub Display(ByVal Me As Person)

Messagebox.Show( Me.name + ", " + str( Me.age ) )

End Sub

End Class

无论是在New()或Display()程序里﹐Me皆固定参考到目前对象﹐您不能改变Me之值。接下来﹐请看如何令Me参考到目前对象﹖假如有个Form1_Click()程序如下﹕

Sub Form1_Click( .... )

Dim x As New Person("Tom", 26)

x.Display()

End Sub

VB在编译时﹐会把指令──x.Display()转换为﹕

Person_Display(x)

意谓着﹕呼叫Person类别的Display()程序来处理x 对象之内容。在呼叫这程序时﹐就把x参考值传递给Display()程序里的Me参数﹐如下﹕

于是﹐Me就固定指向x对象了﹐而这x 对象就是我们欲处理之对象﹐亦

即就是目前对象了。请再看个例子吧﹗若Person类别改为﹕

Class Person

Private name As String

Priavte age As Integer

Public Sun New(ByVal na As String, ByVal a As Integer)

name = na

age = a

End Sub

Public Sub Print()

Me.Display()

End Sub

Public Sub Display()

Messagebox.Show( name + ", " + str( age ) )

End Sub

End Class

则VB会为这3 个程序成员加上Me参考值。其中Print()程序转换如下﹕

Public Sub Print(ByVal Me As Person)

Person_Display( Me )

End Sub

上述的Me.Display()转换为Person_Display( Me )之后﹐就把这Print()内的Me值传给了Display()内的Me了﹐此时两个程序内的Me皆参考到目前对象了。

以上所提的一般程序成员并不包括共享程序成员(Shared Member Function)。还记得吗﹖共享程序成员的目的是﹕处理有关整个类别的事情﹐而不是用来处理对象之内容。在另一方面﹐Me参考到目前对象﹐一般程序成员经由Me来存取目前对象之内容。既然共享程序成员不需存取某特定对象之值﹐当然就不需要Me参考变量了﹐因之VB并不会为共享程序成员偷加上Me参考变量。简而言之﹐VB的规则是──

「VB编译时﹐并不会为共享程序成员加上Me参考变量﹐所以

共享程序成员里没有Me参考变量﹐也就无法存取对象之内容」

如前面所述﹐在呼叫一般程序成员时﹐必须把目前对象之参考值传递过去给该程序成员。但共享程序成员里并无Me参考﹐所以无法呼叫一般程序成员。可得知VB的规则──

「共享程序成员不能呼叫一般程序成员﹐但可呼叫别的共享程序成员」

反之﹐一般程序成员却可呼叫共享程序成员。例如﹕

Class Person

Private name As String

Priavte age As Integer

Shared plast As Person

Public Sun New(ByVal na As String, ByVal a As Integer)

name = na

age = a

plast = Me

End Sub

Shared Sub DispLast()

plast.Display()

'Display() Error !!

End Sub

Public Sub Print()

DispLast()

End Sub

Public Sub Display()

Messagebox.Show( name + ", " + str( age ) )

End Sub

End Class

Display()是一般程序成员﹐共享程序成员DispLast()不能直接呼叫Display()程序如下﹕

Shared Sub DispLast()

Display() Error !!

End Sub

因为VB会将之转换为──

Shared Sub DispLast()

Person_Display( Me ) Error !!

End Sub

但DispLast()是共享程序成员﹐并无Me参考变量﹐所以错了。至于Print()

呼叫DispLast()﹐VB将之转换为──

Public Sub Print( ByVal Me As Person )

Person_DispLast()

End Sub

虽然Print() 内有Me参考﹐但DispLast()是静态程序成员并不需要Me

﹐Print() 并未把Me传给DispLast()﹐这是对的。n

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有