VB.Net中文教程(7) Me參考值 (轉)
請注意 ......
著作權所有人:物澤事業股份有限公司、
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 )。目前物件就是正接受並處理訊息之物件。例如﹐
'ex01.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.s
'------------------------------------------------------------------------------
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 FoDesigner.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrs dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " 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指標之使用場合﹐能讓您寫出完美的程式來﹗現在﹐請看個熟悉的程式──
'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
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988985/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- DOJO API 中文參考手冊API
- MySQL8-中文參考-三-MySql
- 7 Oracle DataGuard 命令列參考Oracle命令列
- MySQL8-中文參考-三十二-MySql
- IOC注入反轉思路-僅供參考
- TIDB 考試 參考TiDB
- OSI參考模型和TCP/IP參考模型模型TCP
- javamail參考JavaAI
- Hbase 中文參考指南 3.0 校對活動發車了~
- 【PyQt5】QComboBox 樣式表參考(轉載)QT
- [PyQt5] QComboBox 樣式表參考(轉載)QT
- 譯-MYSQL5.7參考手冊--數值型別概述MySql型別
- MySQL8.0.28安裝教程全程參考MySQL官方文件MySql
- OSI參考模型詳解之玩轉傳輸層模型
- WebApiClient效能參考WebAPIclient
- OSI參考模型模型
- JavaScript中的函式與命令模式,Java也有參考價值JavaScript函式模式
- 譯-MYSQL5.7參考手冊--11.1.1數值型別概述MySql型別
- Capture One Mac教程:移動參考影像的資料夾APTMac
- Show me the code,babel 7 最佳實踐!Babel
- 模擬考試參考程式碼
- 修改中文、英文參考文獻在文末列表中的順序:EndNote
- 《史丹佛資料探勘教程(第3版)》完整參考文獻
- Blender參考API用法API
- LVS - ipvsadm命令參考
- Oracle ASMCMD命令參考OracleASM
- SQL優化參考SQL優化
- openGauss ODBC介面參考
- Latex—參考文獻
- CloudBeaver 參考架構Cloud架構
- 參考文獻合集
- echarts markLine參考線Echarts
- PyQtGraph繪圖參考QT繪圖
- oracle 參考資料Oracle
- Spring Boot 2.0.2 參考指南(通用的應用程式屬性 ②)中文文件Spring Boot
- C#/VB.NET 將RTF轉為HTMLC#HTML
- C#/VB.NET 將Html轉為ExcelC#HTMLExcel
- RedHat Advance Server上安裝Oracle 9204 RAC參考手冊(轉)RedhatServerOracle
- spring-boot參考文章Springboot