类别之用途为﹕宣告对象。例如﹕‘ex01.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms '---------------------------------------------------- Class Tree Public varity As String Public age As Integer Public height As Single 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 Tree() MsgBox("Object a Is Created.") End Sub End Class此程序定义了类别Tree﹐它只含资料而无程序﹐为一「阳春型」之类别。当计算机执行到Form1_Click()程序内之宣告指令── Dim a As New Tree()就分配足够存放这 3项资料的内存空间给予对象 a。然而﹐此Tree类别只有资料而无程序。所以﹐对象 a无法接受外来之讯息。此时﹐可加入程序成员﹐使Tree类别含有程序、具有动力﹐对象就有能力来处理讯息了。例如﹕‘ex02.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms '------------------------------------------------------------ Class Tree Public varity As String Public age As Integer Public height As Single Public Sub input(ByVal hei As Single) height = hei 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 Tree() a.input(2.1) Messagebox.Show("Set a.Height to 2.1", "Hello!") End Sub End Class此程序输出:Set a.Height to 2.1 现在﹐Tree类别已拥有程序成员 input()。程序成员的写法与一般VB程序相同﹐只是它应宣告于类别内﹐成为类别之专属程序。此刻﹐对象 a含有 3项资料及 1个程序﹕
此刻﹐对象 a对讯息之处理完成了﹐其内部资料改变了﹐亦即对象 a之内部状态(Internal State)改变了﹔这是对象的行为之一。上述您已经会加入一个程序了﹐依同样方法﹐继续加入其它程序﹐让对象的兴为更多采多姿。例如﹕‘ex03.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms ‘----------------------------------------------------------------------- Class Tree Public varity As String Public age As Integer Public height As Single Public Sub input(ByVal hei As Single) height = hei End Sub Public Function inquireHeight() As Single inquireHeight = height 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 a As Tree = New Tree() Dim h As Single a.input(2.1) h = a.inquireHeight() Messagebox.Show("height = " + str(h) + "公尺", "HI!") End Sub End Class此程序输出如下﹕height = 2.1公尺 Tree类别有2个程序成员──input() 和inquireHeight()。类别之程序成员必须与其对象配合使用。格式为﹕
亦即﹐必须以讯息之形式出现。例如﹕
如果程序成员不与对象相配合时﹐计算机会如何处理呢﹖例如﹕‘ex04.bas ‘Some Error Here ! Imports System.ComponentModel Imports System.Drawing Imports System.WinForms '-------------------------------------------------------------- Class Tree Public varity As String Public age As Integer Public height As Single Public Sub input(ByVal hei As Single) height = hei End Sub Public Function inquireHeight() As Single inquireHeight = height 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 a As Tree = New Tree() Dim h As Single a.input(2.1) h = inquireHeight() Messagebox.Show("height = " + str(h) + "公尺", "HI!") End Sub End Class当计算机看到Form1_Click()内之指令── h = inquireHeight( )它视inquireHeight()为一独立之程序﹐与Tree类别内之inquireHeight()无关﹔于是计算机去找此inquireHeight()之定义﹐但找不着﹔所以程序错了。因之﹐您要掌握个原则── 程序成员之唯一任务是支持对象之行为﹐必须与对象配合使用。 2. 「封装性」概念 对象把资料及程序组织并「封装」(Encapsulate) 起来﹐只透过特定的方式才能使用类别之资料成员和程序成员。对象如同手提袋﹐只从固定的开口才能存取东西﹐否则您一定不敢把钱放在手提袋中。对象像一座「防火墙」保护类别中的资料﹐使其不受外界之影响。想一想我国的万里长城可保护关内的人民﹐避免受胡人侵犯﹐但长城并非完全封闭﹐而有山海关、玉门关等出入口。对象和万里长城之功能是一致的﹐它保护其资料成员﹐但也有正常的资料存取管道﹕以程序成员来存取资料成员。请看个程序﹕‘ex05.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms '------------------------------------------------------- Class Tree Public varity As String Public age As Integer Public height As Single 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 Tree() a.height = 2.1 Messagebox.Show("height = " + str(a.height) + "公尺") End Sub End Class此程序输出如下﹕height = 2.1公尺 此程序中﹐Tree类别含有 3个资料成员﹐即对象内含有3个资料值,此类别之程序成员能直接存取之。同时,也允许其它程序来存取资料成员之值﹐其存取格式为﹕
请看个常见错误如下﹕‘ex06.bas ‘Some Error Here! Imports System.ComponentModel Imports System.Drawing Imports System.WinForms '-------------------- ------------------------------------ Class Tree Public varity As String Public age As Integer Public height As Single 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 Tree() height = 2.1 Messagebox.Show("height = " + str(a.height) + "公尺") End Sub End ClassForm1_Click()程序内之指令── height = 2.1,此height变量并未与对象配合使用﹐计算机不认为它是Tree类别之height变量。计算机视其为Form1_Click()之自动变量(Automatic Variable)﹐但却未见到它的宣告﹐因之程序错了﹗这是对象对其资料成员保护最松的情形﹐因为对象所属类别(即Tree)之外的程序(如Form1_Click()程序)尚能存取资料成员的内容。就像一颗炸弹﹐除了引信管外﹐尚有许多管道可使炸弹内之化学药品爆炸﹔您将不敢把炸弹摆在飞机上﹐因何时会爆炸将无法控制。同理﹐Tree类别之资料──height变量﹐连外部的Form1_Click()皆可随意改变它﹔那么有一天height之内容出问题了﹐将难以追查出错之缘故﹐这种程序将让您大伤脑筋﹐因为您已无法掌握状况了。 现在的VB程序中﹐能采取较严密之保护措施﹐使您较能控制类别内资料的变化状况。例如﹐‘ex07.bas ‘Some Error Here! Imports System.ComponentModel Imports System.Drawing Imports System.WinForms '----------------------------------------- Class Tree Private varity As String Private age As Integer Private height As Single 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 Public Sub Form1_Click( ByVal sender As Object, ByVal e As System.EventArgs) Dim a As New Tree() a.height = 2.1 MessageBox.Show("height = " + str(a.height)) End Sub End Class此程序将原来的Public专用字改为Private﹐对Tree类别之资料成员采取严格之保护措施。Public 与Private之区别为── Public 表示此类别外之程序可来存取资料成员。 Private 表示此类别外之程序绝无法直接存取资料成员﹐只有程序成员才能存取资料成员。所以﹐计算机看到指令── a.height = 2.1,因Tree类别采取严格保护措施(private)﹐则Form1_Click()程序不能使用height变量名称。所以指令── a.height = 2.1错了。也许您问道﹕这样岂不是无法存取类别内之资料成员吗﹖答案是﹕「类别内之程序成员(Member Function) 可存取资料成员﹐而类别外之程序能藉程序成员代之存取资料成员。」
图1、类别之沟通管道──程序成员 这如同﹐引信管才能引起炸弹内之化学药品爆炸﹐人们只能经由引信管引爆之﹐让人们觉得使用炸弹既安全又简单。同样地﹐对象经由程序成员和外界沟通﹐可减少外界无意中破坏对象内之资料(无意中引爆炸弹)。例如﹕‘ex08.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms '-------------------------------------------------- Class Tree Private varity As String Private age As Integer Private height As Single Public Sub input(ByVal hei As Single) height = hei 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 Tree() a.input(2.1) MessageBox.Show("OK") End Sub End Class 将input()摆在Tree类别中﹐为Tree之程序成员﹐它能存取资料成员height之值。把input()程序宣告为Public表示类别外之程序可藉来呼叫它﹐其呼叫格式为──
简单规则是﹕ Public 表示授权给外界之程序藉由此格式呼叫程序成员。如果此程序改写为﹕‘ex09.bas ‘Some Error Here! Imports System.ComponentModel Imports System.Drawing Imports System.WinForms '---------------------------------------------- Class Tree Private varity As String Private age As Integer Private height As Single Private Sub input(ByVal hei As Single) height = hei 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 Tree() a.input(2.1) MessageBox("OK") End Sub End Class这程序有问题﹐因为 input()是Tree类别之Private程序成员而非Public程序成员﹐所以不能使用如下格式──
所以此程序错了。 请再看个例子吧﹗‘ex10.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms '------------------------------------------- Class Tree Private varity As String Private height As Single Public age As Integer Public Sub ShowAge() MessageBox.Show("Age = " + str(Age)) 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 Tree() a.age = 8 a.age = a.age + 2 a.ShowAge() End Sub End ClassTree类别包含 2个Private成员── variety及height﹐且有 2个Public成员── age及 ShowAge()。由于age是Public资料成员﹐所以Fom1_Click()可使用格式──
例如﹕‘ex11.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms '-------------------------------------------------------------------- Class Tree Private varity As String Private age As Integer Private height As Single Public Sub input(ByVal v As String, ByVal a As Integer, ByVal hei As Single) varity = v age = a height = hei End Sub Public Sub Show() MessageBox.Show(varity + ", " + str(age) + ", " + str(height)) 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, b As New Tree() a.input("peach", 8, 2.1) b.input("pinapple", 2, 0.5) a.Show() b.Show() End Sub End Class 这个VB程序﹐Tree内之资料成员──variety, age及height皆为Private成员,而input()及Show()程序是Public成员。Form1_Click()程序中﹐首先诞生对象── a及 b。接下来﹐指令──
请注意 ...... 著作权所有人:物泽计算机事业股份有限公司、 MISOO对象技术顾问团队、对象导向杂志作者、等。 u本文件摘自 对象导向杂志、精通对象观念与技术等书籍著作。 u本文件仅供您的参阅,请遵守著作权法,不得做其它商业用途。主题: 对象自变量(Argument) ¾¾¾¾¾¾ 内容 ¾¾¾¾¾¾ v 1. 对象自变量 v 2. 传回对象之参考 1. 对象自变量 程序(Procedure)之间常藉自变量(Argument)相互传递资料。自变量之型态除了常见的 String、Integer、 Double等一般资料型态外﹐也能为类别资料型态。因之﹐您能将对象资料传递给别的程序﹐这就是「对象自变量」(Object Argument) 。请看个简单程序﹐它可求长方形面积。从这文字叙述── 求长方形面积﹐可联想到﹕「长方形」应为类别﹐而某个长方形就是对象﹐于是着手设计类别叫 Rectangle﹐亦即创造一种叫 Rectangle之资料型态来描述长方形之特性──长与宽。‘ex01.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms '----------------------------------------------------------------------------------- Class Rectangle Private height As Integer Private width As Integer Public Sub New(ByVal hei As Integer, ByVal wid As Integer) height = hei width = wid End Sub Public Sub area() 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, r2 As Rectangle r1 = New Rectangle(10, 10) r2 = New Rectangle(8, 6) r1.area() r2.area() End Sub End Class此程序输出如下﹕ Area = 100 Area = 48 Rectangle 是资料型态。r1及r2就是其对象﹐各代表一个长方形﹐亦即各储存一个长方形之长和宽。此程序相当于──‘ex02.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms '------------------------------------------------------------- Public Class Rectangle Private height As Integer Private width As Integer Public Sub New(ByVal hei As Integer, ByVal wid As Integer) height = hei width = wid End Sub Public Sub area() 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 Public Sub display(ByVal x As Rectangle) x.area() End Sub Protected Sub Form1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Dim r1, r2 As Rectangle r1 = New Rectangle(10, 10) r2 = New Rectangle(8, 6) display(r1) display(r2) End Sub End Class此程序输出如下﹕ Area = 100 Area = 48Form1_Click()程序把对象r1及r2分别传给 display()程序。 由于r1及 r2 的型态是Rectangle﹐所以 display()程序也以相同型态的变量接受之。x 的型态是Rectangle﹐刚好可接受Form1_Click()传递来之对象。Form1_Click()程序中的呼叫指令── display( r1 ); 它把对象r1的参考值(Reference)拷贝给参数(Parameter)x。于是x就相当于r1了﹐您可以将x视为r1的别名,两者皆代表同一个(The Same)对象﹐只是使用场合不同罢了── 不同的情形就是:在Form1_Click()程序里只能使用r1这个名称﹐而在display()程序里只能使用x名称来称呼那个对象。所以display() 中的指令── x.area(),它叫area()程序把 x所代表之长方形面积计算出来。此程序相当于──‘ex03.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms '------------------------------------------------------------- Public Class Rectangle Private height As Integer Private width As Integer Public Sub New(ByVal hei As Integer, ByVal wid As Integer) height = hei width = wid End Sub Public Sub area() 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 Public Sub display(ByVal x As Rectangle, ByVal y As Rectangle) x.area() y.area() End Sub Protected Sub Form1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Dim r1, r2 As Rectangle r1 = New Rectangle(10, 10) r2 = New Rectangle(8, 6) display(r1, r2) End Sub End Class此程序输出如下﹕ Area = 100 Area = 48Form1_Click()内之指令── display( r1, r2 ) 把对象r1的参考值拷贝给新x且把对象r2之参考值拷贝给y 。于是 r1与x代表同一个对象,r1对象的内容和x对象内容完全一样,同理r2对象之内容和y对象内容一样。 请您再看个程序﹐它将长方形面积减去圆之面积。由于我们考虑到长方形和圆形﹐于是设计两个类别──Rectangle 及Circle表达其形状,如下:‘ex04.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms '----------------------------------------------------------------- Public Class Circle Private radius As Integer Public Sub New(ByVal r As Integer) radius = r End Sub Public Function area() As Double area = radius * radius * 3.1416 End Function End ClassPublic Class Rectangle Private height As Integer Private width As Integer Public Sub New(ByVal hei As Integer, ByVal wid As Integer) height = hei width = wid End Sub Public Function area() As Double area = height * width 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 Public Sub displayDelta(ByVal r As Rectangle, ByVal c As Circle) Dim delta As Double delta = r.area() - c.area() MessageBox.Show("Delta = " + str(delta)) End Sub Protected Sub Form1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Dim r1 As New Rectangle(25, 20) Dim c1 As New Circle(10) displayDelta(r1, c1) End Sub End Class此程序输出如下﹕Delta = 185.84 这里的displayDelta()是Form1类别的成员,它接受两个对象,求算其面积的差值。这displayDelta()也能搬移到Rectangle类别里面,如下:‘ex05.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms '------------------------------------------------------------- Public Class Circle Private radius As Integer Public Sub New(ByVal r As Integer) radius = r End Sub Public Function area() As Double area = radius * radius * 3.1416 End Function End ClassPublic Class Rectangle Private height As Integer Private width As Integer Public Sub New(ByVal hei As Integer, ByVal wid As Integer) height = hei width = wid End Sub Public Function area() As Double area = height * width End Function Public Sub displayDelta(ByVal c As Circle) Dim delta As Double delta = Me.area() - c.area() MessageBox.Show("Delta = " + str(delta)) 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(25, 20) Dim c1 As New Circle(10) r1.displayDelta(c1) End Sub End Class此程序输出: Delta = 185.84 以上介绍了如何把对象传递给程序﹐在VB里﹐传递对象也就是传递对象的参考值﹐再简单不过了。 2. 细说对象自变量 下述指令: Dim r1 As New Rectangle( .... )相当于: Dim r1 As Rectangle r1 = New Rectangle( .... ) 先宣告r1为参考变量,指向Rectangle类别的对象。此时,下述两种说法都是对的: 1) 诞生一个Rectangle对象,取名为r1。 2) 诞生一个Rectangle对象,把它的参考值存入r1变量里。例如﹕‘ex07.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms ‘----------------------------------------------------------------------------------------- Public Class BankAccount Private account_no As Integer Private saving As Double Public Sub New(ByVal a As Integer, ByVal s As Double) account_no = a saving = s End Sub Public Sub report() MessageBox.Show("AccNo=" + str(account_no) + " Saving=" + str(saving)) 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 Private Sub report(ByVal xcc As BankAccount) xcc.report() End Sub Protected Sub Form1_Click( ByVal sender As Object, ByVal e As System.EventArgs) Dim acc As New BankAccount(888, 950.8) Me.report( acc ) End Sub End Class此程序输出如下﹕AccNo=888 Saving=950.8 New BankAccount()诞生一个新对象,并将它的参考值存入acc变量里。此时acc变量含有这新诞生的对象之参考值,就称acc参考到(reference to)该对象,也称acc是该对象的名称,或干脆称为acc对象。可表示为: 或
或
在此程序中﹐Form1_Click()程序把对象之参考值传递给report()程序。同样地﹐也能把对象之参考值传递给自己类别之程序成员﹐其方法是一致的。例如﹐把上述程序的report()移入BankAccount类别中﹕‘ex08.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms ‘---------------------------------------------------------------------------------------- Public Class BankAccount Private account_no As Integer Private saving As Double Public Sub New(ByVal a As Integer, ByVal s As Double) account_no = a saving = s End Sub Public Sub report() MessageBox.Show( "AccNo=" + str(account_no) + " Saving=" + str(saving)) End Sub Public Sub report(ByVal xcc As BankAccount) xcc.report() 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 lily As New BankAccount(888, 950.8) Dim tom As New BankAccount(747, 2346.5) tom.report() tom.report(lily) End Sub End Class此程序输出如下﹕ AccNo=747 Saving=2346.5 AccNo=888 Saving=950.8 此类别定义了两个report()程序﹐这是report()的多重定义﹔当您呼叫report()时可传递对象参考给它﹐也可不传资料给它﹐共有两种选择。当计算机执行到指令── tom.report(),因未含自变量﹐就呼叫前面的report()﹐显示出 tom对象中的资料。 至于另一指令── tom.report( lily ) ;Fom1_Click()把lily对象之参考传递给report()。因有自变量﹐且lily之型态与xcc之型态相合﹐于是呼叫第2个report()程序──report(ByVal xcc As BankAccount)﹔并且把 lily对象之参考值传给xcc﹐使xcc也参考到lily对象。
图 4.10 对象之传递此图就相当于:
由于xcc.report()表示呼叫lily之report()程序。因之﹐上述程序的Form1_Click()呼叫tom之report(ByVal xcc As BankAccount)程序﹐而此report()再呼叫lily之report()程序。结果真正做事的是lily之report()程序﹐于是输出了lily对象的资料。请您看下述程序做些什么﹖‘ex09.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms ‘---------------------------------------------------------------------------------- Public Class BankAccount Private account_no As Integer Private saving As Double Public Sub New(ByVal a As Integer, ByVal s As Double) account_no = a saving = s End Sub Public Sub transfer_out(ByVal bac As BankAccount) bac.saving = bac.saving + saving saving = 0 End Sub Public Sub report() MessageBox.Show("AccNo=" + str(account_no) + " Saving=" + str(saving)) 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 lily As New BankAccount(888, 950.8) Dim tom As New BankAccount(747, 2346.5) tom.transfer_out(lily) lily.report() tom.report() End Sub End Class此程序输出如下﹕ AccNo=888 Saving=3297.3 AccNo=747 Saving=0 此程序把 tom之存款额全部转到lily帐户中。当计算机执行到指令── tom.transfer_out( lily )时﹐bac正参考到lily对象。因之﹐transfer_out()内之指令── 把 tom之saving值全部加到lily之saving变量中。反之﹐如果想把lily的存款额转入 tom帐户中﹐则宜为BankAccount类别增添一个程序成员如下﹕ Public Sub transfer_in(ByVal bac As BankAccount) saving = saving + bac.saving bac.saving = 0 End Sub 2. 传回对象之参考 前面所介绍,大都是将对象参考传递给别的子程序,反之该子程序也能将某个对象的参考回传给主程序。学VB的过程中﹐许多人对「参考值」(Reference) 的观念感到头大﹐不易接受。然而﹐这是常用之观念﹔希望您能充分了解它﹐才能善用VB语言。现在﹐回味「参考变量」(Reference Variable)的观念﹐请看程序吧﹗‘ex10.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms ‘------------------------------------------------------------------------- Public Class Fee Public amount As Double Public Sub New(ByVal amt As Double) amount = amt 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 Public Sub disp(ByVal money As Fee) MessageBox.Show("Money = " + str(money.amount)) End Sub Protected Sub Form1_Click( ByVal sender As Object, ByVal e As System.EventArgs) Dim salary As New Fee(388.55) Me.disp(salary) End Sub End Class此程序输出﹕Money = 388.55 disp()程序之定义 ── Sub disp(ByVal money As Fee) ...... End Sub说明了 money为 Fee类别型态之变量﹐于是Form1_Click()的指令── Me.disp (salary) 将salary之参考值传给 money﹐使得 money与salary重合在一起﹐代表同一个对象,其值相同。此为著名的「参考呼叫」(Call by Reference) 法。必要时﹐亦可将money内的参考值传回Form1_Click()。例如﹕‘ex11.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms ‘-------------------------------------------------------- Public Class Fee Public amount As Double Public Sub New(ByVal amt As Double) amount = amt 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 Public Function change(ByVal money As Fee) As Fee money.amount = money.amount + 100 change = money End Function Protected Sub Form1_Click( ByVal sender As Object, ByVal e As System.EventArgs) Dim salary As New Fee(2500.5) Dim x As Fee x = change(salary) MessageBox.Show("x = " + str(x.amount) + " salary = " + str(salary.amount)) End Sub End Class此程序输出﹕ x= 2600.5 salary= 2600.5 由于money是salary的别名,代表同一个对象,也就是money与salary重合在一起﹐所以指令── money.amount = money.amount + 100相当于── salary.amount = salary.amount + 100 使得 money与salary对象之内容皆变成 2600.5 。 change()程序的定义如下﹕ 于是change() 把 money之参考值传回Form1_Click()。此刻﹐change(salary)之值也是参考值,与money参考到同一个对象。 此程序之各项资料皆靠参考值传递。 使得 money、change(salary)及 x皆为salary之别名﹐它们和salary皆参考到同一个对象。 这就参考传递的奇妙景象。现在﹐请看看下述程序﹐藉之深入了解参考传递法了。‘ex12.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms ‘------------------------------------------------------------------ Public Class Fee Public amount As Double Public Sub New(ByVal amt As Double) amount = amt 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 Public Function change(ByVal money As Fee) As Fee money.amount = money.amount + 100 change = money End Function Protected Sub Form1_Click( ByVal sender As Object, ByVal e As System.EventArgs) Dim salary As New Fee(2500.5) Dim pay As Fee pay = change(change(change(salary))) MessageBox.Show("x=" + str(pay.amount) + " salary=" + str(salary.amount)) End Sub End Class此程序输出如下﹕ x=2800.5 Salary = 2800.5原来的salary值是2500.5。
著作权所有人:物泽计算机事业股份有限公司、
MISOO对象技术顾问团队、对象导向杂志作者、等。
u本文件摘自 对象导向杂志、精通对象观念与技术等书籍著作。
u本文件仅供您的参阅,请遵守著作权法,不得做其它商业用途。主题: 类别与封装性(Ecapsulation)¾¾¾¾¾¾¾¾¾¾¾¾ 内容 ¾¾¾¾¾¾¾¾¾¾¾¾
v 1. 类别的「程序成员」
v 2. 「封装性」概念
1. 类别的「程序成员」(Procedure Member) 类别 (Class)之任务是把资料(Data)和程序(Procedure)组织并封装起来。类别告诉计算机﹕「其对象应含有那些资料、应含有那些程序裨处理外界传来之讯息」。类别须详细说明它的资料及程序﹐我们称此资料是类别之「资料成员」(Data Member) ﹔而称此程序是类别之「程序成员」(Procedure Member)。有关类别内容之叙述﹐就是所谓的类别定义(Class Definition)。类别定义之格式为──
类别之用途为﹕宣告对象。例如﹕‘ex01.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'----------------------------------------------------
Class Tree
Public varity As String
Public age As Integer
Public height As Single
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 Tree()
MsgBox("Object a Is Created.")
End Sub
End Class此程序定义了类别Tree﹐它只含资料而无程序﹐为一「阳春型」之类别。当计算机执行到Form1_Click()程序内之宣告指令──
Dim a As New Tree()就分配足够存放这 3项资料的内存空间给予对象 a。然而﹐此Tree类别只有资料而无程序。所以﹐对象 a无法接受外来之讯息。此时﹐可加入程序成员﹐使Tree类别含有程序、具有动力﹐对象就有能力来处理讯息了。例如﹕‘ex02.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'------------------------------------------------------------
Class Tree
Public varity As String
Public age As Integer
Public height As Single
Public Sub input(ByVal hei As Single)
height = hei
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 Tree()
a.input(2.1)
Messagebox.Show("Set a.Height to 2.1", "Hello!")
End Sub
End Class此程序输出:Set a.Height to 2.1
现在﹐Tree类别已拥有程序成员 input()。程序成员的写法与一般VB程序相同﹐只是它应宣告于类别内﹐成为类别之专属程序。此刻﹐对象 a含有 3项资料及 1个程序﹕
计算机执行到指令──
a.input(2.1)就将讯息──input(2.1)传给对象 a。此时计算机呼叫并执行对象 a内之input() 程序。对象 a内之 input()就是定义于Tree类别内之input() ﹔于是Form1_Click()就把自变量──2.1 传给 input()内之 hei变量。
接下来﹐叙述──
height = hei把 hei变量值存入对象 a之资料成员──height中。
此刻﹐对象 a对讯息之处理完成了﹐其内部资料改变了﹐亦即对象 a之内部状态(Internal State)改变了﹔这是对象的行为之一。上述您已经会加入一个程序了﹐依同样方法﹐继续加入其它程序﹐让对象的兴为更多采多姿。例如﹕‘ex03.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
‘-----------------------------------------------------------------------
Class Tree
Public varity As String
Public age As Integer
Public height As Single
Public Sub input(ByVal hei As Single)
height = hei
End Sub
Public Function inquireHeight() As Single
inquireHeight = height
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 a As Tree = New Tree()
Dim h As Single
a.input(2.1)
h = a.inquireHeight()
Messagebox.Show("height = " + str(h) + "公尺", "HI!")
End Sub
End Class此程序输出如下﹕height = 2.1公尺
Tree类别有2个程序成员──input() 和inquireHeight()。类别之程序成员必须与其对象配合使用。格式为﹕
亦即﹐必须以讯息之形式出现。例如﹕
如果程序成员不与对象相配合时﹐计算机会如何处理呢﹖例如﹕‘ex04.bas
‘Some Error Here !
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'--------------------------------------------------------------
Class Tree
Public varity As String
Public age As Integer
Public height As Single
Public Sub input(ByVal hei As Single)
height = hei
End Sub
Public Function inquireHeight() As Single
inquireHeight = height
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 a As Tree = New Tree()
Dim h As Single
a.input(2.1)
h = inquireHeight()
Messagebox.Show("height = " + str(h) + "公尺", "HI!")
End Sub
End Class当计算机看到Form1_Click()内之指令──
h = inquireHeight( )它视inquireHeight()为一独立之程序﹐与Tree类别内之inquireHeight()无关﹔于是计算机去找此inquireHeight()之定义﹐但找不着﹔所以程序错了。因之﹐您要掌握个原则── 程序成员之唯一任务是支持对象之行为﹐必须与对象配合使用。
2. 「封装性」概念 对象把资料及程序组织并「封装」(Encapsulate) 起来﹐只透过特定的方式才能使用类别之资料成员和程序成员。对象如同手提袋﹐只从固定的开口才能存取东西﹐否则您一定不敢把钱放在手提袋中。对象像一座「防火墙」保护类别中的资料﹐使其不受外界之影响。想一想我国的万里长城可保护关内的人民﹐避免受胡人侵犯﹐但长城并非完全封闭﹐而有山海关、玉门关等出入口。对象和万里长城之功能是一致的﹐它保护其资料成员﹐但也有正常的资料存取管道﹕以程序成员来存取资料成员。请看个程序﹕‘ex05.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-------------------------------------------------------
Class Tree
Public varity As String
Public age As Integer
Public height As Single
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 Tree()
a.height = 2.1
Messagebox.Show("height = " + str(a.height) + "公尺")
End Sub
End Class此程序输出如下﹕height = 2.1公尺
此程序中﹐Tree类别含有 3个资料成员﹐即对象内含有3个资料值,此类别之程序成员能直接存取之。同时,也允许其它程序来存取资料成员之值﹐其存取格式为﹕
例如﹕
a.height = 2.1此指令把 2.1存入对象 a之height变量中。于是对象 a之内容为﹕
请看个常见错误如下﹕‘ex06.bas
‘Some Error Here!
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-------------------- ------------------------------------
Class Tree
Public varity As String
Public age As Integer
Public height As Single
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 Tree()
height = 2.1
Messagebox.Show("height = " + str(a.height) + "公尺")
End Sub
End ClassForm1_Click()程序内之指令── height = 2.1,此height变量并未与对象配合使用﹐计算机不认为它是Tree类别之height变量。计算机视其为Form1_Click()之自动变量(Automatic Variable)﹐但却未见到它的宣告﹐因之程序错了﹗这是对象对其资料成员保护最松的情形﹐因为对象所属类别(即Tree)之外的程序(如Form1_Click()程序)尚能存取资料成员的内容。就像一颗炸弹﹐除了引信管外﹐尚有许多管道可使炸弹内之化学药品爆炸﹔您将不敢把炸弹摆在飞机上﹐因何时会爆炸将无法控制。同理﹐Tree类别之资料──height变量﹐连外部的Form1_Click()皆可随意改变它﹔那么有一天height之内容出问题了﹐将难以追查出错之缘故﹐这种程序将让您大伤脑筋﹐因为您已无法掌握状况了。
现在的VB程序中﹐能采取较严密之保护措施﹐使您较能控制类别内资料的变化状况。例如﹐‘ex07.bas
‘Some Error Here!
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-----------------------------------------
Class Tree
Private varity As String
Private age As Integer
Private height As Single
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
Public Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim a As New Tree()
a.height = 2.1
MessageBox.Show("height = " + str(a.height))
End Sub
End Class此程序将原来的Public专用字改为Private﹐对Tree类别之资料成员采取严格之保护措施。Public 与Private之区别为── Public 表示此类别外之程序可来存取资料成员。
Private 表示此类别外之程序绝无法直接存取资料成员﹐只有程序成员才能存取资料成员。所以﹐计算机看到指令── a.height = 2.1,因Tree类别采取严格保护措施(private)﹐则Form1_Click()程序不能使用height变量名称。所以指令── a.height = 2.1错了。也许您问道﹕这样岂不是无法存取类别内之资料成员吗﹖答案是﹕「类别内之程序成员(Member Function) 可存取资料成员﹐而类别外之程序能藉程序成员代之存取资料成员。」
图1、类别之沟通管道──程序成员 这如同﹐引信管才能引起炸弹内之化学药品爆炸﹐人们只能经由引信管引爆之﹐让人们觉得使用炸弹既安全又简单。同样地﹐对象经由程序成员和外界沟通﹐可减少外界无意中破坏对象内之资料(无意中引爆炸弹)。例如﹕‘ex08.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'--------------------------------------------------
Class Tree
Private varity As String
Private age As Integer
Private height As Single
Public Sub input(ByVal hei As Single)
height = hei
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 Tree()
a.input(2.1)
MessageBox.Show("OK")
End Sub
End Class 将input()摆在Tree类别中﹐为Tree之程序成员﹐它能存取资料成员height之值。把input()程序宣告为Public表示类别外之程序可藉来呼叫它﹐其呼叫格式为──
简单规则是﹕
Public 表示授权给外界之程序藉由此格式呼叫程序成员。如果此程序改写为﹕‘ex09.bas
‘Some Error Here!
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'----------------------------------------------
Class Tree
Private varity As String
Private age As Integer
Private height As Single
Private Sub input(ByVal hei As Single)
height = hei
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 Tree()
a.input(2.1)
MessageBox("OK")
End Sub
End Class这程序有问题﹐因为 input()是Tree类别之Private程序成员而非Public程序成员﹐所以不能使用如下格式──
所以此程序错了。 请再看个例子吧﹗‘ex10.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-------------------------------------------
Class Tree
Private varity As String
Private height As Single
Public age As Integer
Public Sub ShowAge()
MessageBox.Show("Age = " + str(Age))
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 Tree()
a.age = 8
a.age = a.age + 2
a.ShowAge()
End Sub
End ClassTree类别包含 2个Private成员── variety及height﹐且有 2个Public成员── age及 ShowAge()。由于age是Public资料成员﹐所以Fom1_Click()可使用格式──
来存取Tree内之age变量。指令── a.age = 8把8存入对象 a内之age 变量。指令──a.age = a.age + 2使对象a之age变量值加上2﹐成为10。由于ShowAge()程序是Public程序成员﹐也可使用格式──
来呼叫 ShowAge()程序。
由于类别(即对象)之目的是保护资料﹐并且提供程序成员来与外界沟通(接受、处理、并反应讯息)。通常﹐资料成员皆宣告为Private﹐而程序成员皆宣告为Public。亦即尽量少用格式──
而尽量多用格式──
例如﹕‘ex11.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'--------------------------------------------------------------------
Class Tree
Private varity As String
Private age As Integer
Private height As Single
Public Sub input(ByVal v As String, ByVal a As Integer, ByVal hei As Single)
varity = v
age = a
height = hei
End Sub
Public Sub Show()
MessageBox.Show(varity + ", " + str(age) + ", " + str(height))
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, b As New Tree()
a.input("peach", 8, 2.1)
b.input("pinapple", 2, 0.5)
a.Show()
b.Show()
End Sub
End Class 这个VB程序﹐Tree内之资料成员──variety, age及height皆为Private成员,而input()及Show()程序是Public成员。Form1_Click()程序中﹐首先诞生对象── a及 b。接下来﹐指令──
把 3项资料分别存入对象 a之资料成员中﹐a 之内容为﹕
同样地﹐指令──
b.input( "pineapple", 2, 0.5 )也把 3项资料存入对象 b之中﹐则 b之内容为﹕
最后﹐呼叫Show()程序把对象 a和对象 b之内容显示出来﹕
peach, 8, 2.1
pineapple, 2, .5
n
著作权所有人:物泽计算机事业股份有限公司、
MISOO对象技术顾问团队、对象导向杂志作者、等。
u本文件摘自 对象导向杂志、精通对象观念与技术等书籍著作。
u本文件仅供您的参阅,请遵守著作权法,不得做其它商业用途。主题: 对象自变量(Argument)
¾¾¾¾¾¾ 内容 ¾¾¾¾¾¾
v 1. 对象自变量
v 2. 传回对象之参考 1. 对象自变量
程序(Procedure)之间常藉自变量(Argument)相互传递资料。自变量之型态除了常见的 String、Integer、 Double等一般资料型态外﹐也能为类别资料型态。因之﹐您能将对象资料传递给别的程序﹐这就是「对象自变量」(Object Argument) 。请看个简单程序﹐它可求长方形面积。从这文字叙述── 求长方形面积﹐可联想到﹕「长方形」应为类别﹐而某个长方形就是对象﹐于是着手设计类别叫 Rectangle﹐亦即创造一种叫 Rectangle之资料型态来描述长方形之特性──长与宽。‘ex01.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-----------------------------------------------------------------------------------
Class Rectangle
Private height As Integer
Private width As Integer
Public Sub New(ByVal hei As Integer, ByVal wid As Integer)
height = hei
width = wid
End Sub
Public Sub area()
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, r2 As Rectangle
r1 = New Rectangle(10, 10)
r2 = New Rectangle(8, 6)
r1.area()
r2.area()
End Sub
End Class此程序输出如下﹕ Area = 100
Area = 48 Rectangle 是资料型态。r1及r2就是其对象﹐各代表一个长方形﹐亦即各储存一个长方形之长和宽。此程序相当于──‘ex02.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-------------------------------------------------------------
Public Class Rectangle
Private height As Integer
Private width As Integer
Public Sub New(ByVal hei As Integer, ByVal wid As Integer)
height = hei
width = wid
End Sub
Public Sub area()
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
Public Sub display(ByVal x As Rectangle)
x.area()
End Sub
Protected Sub Form1_Click(ByVal sender As Object, ByVal
e As System.EventArgs)
Dim r1, r2 As Rectangle
r1 = New Rectangle(10, 10)
r2 = New Rectangle(8, 6)
display(r1)
display(r2)
End Sub
End Class此程序输出如下﹕ Area = 100
Area = 48Form1_Click()程序把对象r1及r2分别传给 display()程序。
由于r1及 r2 的型态是Rectangle﹐所以 display()程序也以相同型态的变量接受之。x 的型态是Rectangle﹐刚好可接受Form1_Click()传递来之对象。Form1_Click()程序中的呼叫指令── display( r1 ); 它把对象r1的参考值(Reference)拷贝给参数(Parameter)x。于是x就相当于r1了﹐您可以将x视为r1的别名,两者皆代表同一个(The Same)对象﹐只是使用场合不同罢了── 不同的情形就是:在Form1_Click()程序里只能使用r1这个名称﹐而在display()程序里只能使用x名称来称呼那个对象。所以display() 中的指令── x.area(),它叫area()程序把 x所代表之长方形面积计算出来。此程序相当于──‘ex03.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-------------------------------------------------------------
Public Class Rectangle
Private height As Integer
Private width As Integer
Public Sub New(ByVal hei As Integer, ByVal wid As Integer)
height = hei
width = wid
End Sub
Public Sub area()
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
Public Sub display(ByVal x As Rectangle, ByVal y As Rectangle)
x.area()
y.area()
End Sub
Protected Sub Form1_Click(ByVal sender As Object, ByVal
e As System.EventArgs)
Dim r1, r2 As Rectangle
r1 = New Rectangle(10, 10)
r2 = New Rectangle(8, 6)
display(r1, r2)
End Sub
End Class此程序输出如下﹕ Area = 100
Area = 48Form1_Click()内之指令──
display( r1, r2 ) 把对象r1的参考值拷贝给新x且把对象r2之参考值拷贝给y 。于是 r1与x代表同一个对象,r1对象的内容和x对象内容完全一样,同理r2对象之内容和y对象内容一样。
请您再看个程序﹐它将长方形面积减去圆之面积。由于我们考虑到长方形和圆形﹐于是设计两个类别──Rectangle 及Circle表达其形状,如下:‘ex04.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-----------------------------------------------------------------
Public Class Circle
Private radius As Integer
Public Sub New(ByVal r As Integer)
radius = r
End Sub
Public Function area() As Double
area = radius * radius * 3.1416
End Function
End ClassPublic Class Rectangle
Private height As Integer
Private width As Integer
Public Sub New(ByVal hei As Integer, ByVal wid As Integer)
height = hei
width = wid
End Sub
Public Function area() As Double
area = height * width
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
Public Sub displayDelta(ByVal r As Rectangle, ByVal c As Circle)
Dim delta As Double
delta = r.area() - c.area()
MessageBox.Show("Delta = " + str(delta))
End Sub
Protected Sub Form1_Click(ByVal sender As Object, ByVal
e As System.EventArgs)
Dim r1 As New Rectangle(25, 20)
Dim c1 As New Circle(10)
displayDelta(r1, c1)
End Sub
End Class此程序输出如下﹕Delta = 185.84
这里的displayDelta()是Form1类别的成员,它接受两个对象,求算其面积的差值。这displayDelta()也能搬移到Rectangle类别里面,如下:‘ex05.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-------------------------------------------------------------
Public Class Circle
Private radius As Integer
Public Sub New(ByVal r As Integer)
radius = r
End Sub
Public Function area() As Double
area = radius * radius * 3.1416
End Function
End ClassPublic Class Rectangle
Private height As Integer
Private width As Integer
Public Sub New(ByVal hei As Integer, ByVal wid As Integer)
height = hei
width = wid
End Sub
Public Function area() As Double
area = height * width
End Function
Public Sub displayDelta(ByVal c As Circle)
Dim delta As Double
delta = Me.area() - c.area()
MessageBox.Show("Delta = " + str(delta))
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(25, 20)
Dim c1 As New Circle(10)
r1.displayDelta(c1)
End Sub
End Class此程序输出: Delta = 185.84 以上介绍了如何把对象传递给程序﹐在VB里﹐传递对象也就是传递对象的参考值﹐再简单不过了。
2. 细说对象自变量 下述指令:
Dim r1 As New Rectangle( .... )相当于:
Dim r1 As Rectangle
r1 = New Rectangle( .... ) 先宣告r1为参考变量,指向Rectangle类别的对象。此时,下述两种说法都是对的:
1) 诞生一个Rectangle对象,取名为r1。
2) 诞生一个Rectangle对象,把它的参考值存入r1变量里。例如﹕‘ex07.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
‘-----------------------------------------------------------------------------------------
Public Class BankAccount
Private account_no As Integer
Private saving As Double
Public Sub New(ByVal a As Integer, ByVal s As Double)
account_no = a
saving = s
End Sub
Public Sub report()
MessageBox.Show("AccNo=" + str(account_no) + " Saving="
+ str(saving))
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
Private Sub report(ByVal xcc As BankAccount)
xcc.report()
End Sub
Protected Sub Form1_Click( ByVal sender As Object,
ByVal e As System.EventArgs)
Dim acc As New BankAccount(888, 950.8)
Me.report( acc )
End Sub
End Class此程序输出如下﹕AccNo=888 Saving=950.8 New BankAccount()诞生一个新对象,并将它的参考值存入acc变量里。此时acc变量含有这新诞生的对象之参考值,就称acc参考到(reference to)该对象,也称acc是该对象的名称,或干脆称为acc对象。可表示为:
或
或
在此程序中﹐Form1_Click()程序把对象之参考值传递给report()程序。同样地﹐也能把对象之参考值传递给自己类别之程序成员﹐其方法是一致的。例如﹐把上述程序的report()移入BankAccount类别中﹕‘ex08.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
‘----------------------------------------------------------------------------------------
Public Class BankAccount
Private account_no As Integer
Private saving As Double
Public Sub New(ByVal a As Integer, ByVal s As Double)
account_no = a
saving = s
End Sub
Public Sub report()
MessageBox.Show( "AccNo=" + str(account_no) + " Saving="
+ str(saving))
End Sub
Public Sub report(ByVal xcc As BankAccount)
xcc.report()
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 lily As New BankAccount(888, 950.8)
Dim tom As New BankAccount(747, 2346.5)
tom.report()
tom.report(lily)
End Sub
End Class此程序输出如下﹕
AccNo=747 Saving=2346.5
AccNo=888 Saving=950.8 此类别定义了两个report()程序﹐这是report()的多重定义﹔当您呼叫report()时可传递对象参考给它﹐也可不传资料给它﹐共有两种选择。当计算机执行到指令── tom.report(),因未含自变量﹐就呼叫前面的report()﹐显示出 tom对象中的资料。
至于另一指令── tom.report( lily ) ;Fom1_Click()把lily对象之参考传递给report()。因有自变量﹐且lily之型态与xcc之型态相合﹐于是呼叫第2个report()程序──report(ByVal xcc As BankAccount)﹔并且把 lily对象之参考值传给xcc﹐使xcc也参考到lily对象。
图 4.10 对象之传递此图就相当于:
由于xcc.report()表示呼叫lily之report()程序。因之﹐上述程序的Form1_Click()呼叫tom之report(ByVal xcc As BankAccount)程序﹐而此report()再呼叫lily之report()程序。结果真正做事的是lily之report()程序﹐于是输出了lily对象的资料。请您看下述程序做些什么﹖‘ex09.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
‘----------------------------------------------------------------------------------
Public Class BankAccount
Private account_no As Integer
Private saving As Double
Public Sub New(ByVal a As Integer, ByVal s As Double)
account_no = a
saving = s
End Sub
Public Sub transfer_out(ByVal bac As BankAccount)
bac.saving = bac.saving + saving
saving = 0
End Sub
Public Sub report()
MessageBox.Show("AccNo=" + str(account_no) + " Saving="
+ str(saving))
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 lily As New BankAccount(888, 950.8)
Dim tom As New BankAccount(747, 2346.5)
tom.transfer_out(lily)
lily.report()
tom.report()
End Sub
End Class此程序输出如下﹕
AccNo=888 Saving=3297.3
AccNo=747 Saving=0 此程序把 tom之存款额全部转到lily帐户中。当计算机执行到指令── tom.transfer_out( lily )时﹐bac正参考到lily对象。因之﹐transfer_out()内之指令──
把 tom之saving值全部加到lily之saving变量中。反之﹐如果想把lily的存款额转入 tom帐户中﹐则宜为BankAccount类别增添一个程序成员如下﹕ Public Sub transfer_in(ByVal bac As BankAccount)
saving = saving + bac.saving
bac.saving = 0
End Sub
2. 传回对象之参考 前面所介绍,大都是将对象参考传递给别的子程序,反之该子程序也能将某个对象的参考回传给主程序。学VB的过程中﹐许多人对「参考值」(Reference) 的观念感到头大﹐不易接受。然而﹐这是常用之观念﹔希望您能充分了解它﹐才能善用VB语言。现在﹐回味「参考变量」(Reference Variable)的观念﹐请看程序吧﹗‘ex10.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
‘-------------------------------------------------------------------------
Public Class Fee
Public amount As Double
Public Sub New(ByVal amt As Double)
amount = amt
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
Public Sub disp(ByVal money As Fee)
MessageBox.Show("Money = " + str(money.amount))
End Sub
Protected Sub Form1_Click( ByVal sender As Object,
ByVal e As System.EventArgs)
Dim salary As New Fee(388.55)
Me.disp(salary)
End Sub
End Class此程序输出﹕Money = 388.55
disp()程序之定义 ── Sub disp(ByVal money As Fee)
......
End Sub说明了 money为 Fee类别型态之变量﹐于是Form1_Click()的指令──
Me.disp (salary) 将salary之参考值传给 money﹐使得 money与salary重合在一起﹐代表同一个对象,其值相同。此为著名的「参考呼叫」(Call by Reference) 法。必要时﹐亦可将money内的参考值传回Form1_Click()。例如﹕‘ex11.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
‘--------------------------------------------------------
Public Class Fee
Public amount As Double
Public Sub New(ByVal amt As Double)
amount = amt
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
Public Function change(ByVal money As Fee) As Fee
money.amount = money.amount + 100
change = money
End Function
Protected Sub Form1_Click( ByVal sender As Object,
ByVal e As System.EventArgs)
Dim salary As New Fee(2500.5)
Dim x As Fee
x = change(salary)
MessageBox.Show("x = " + str(x.amount) + " salary = "
+ str(salary.amount))
End Sub
End Class此程序输出﹕
x= 2600.5 salary= 2600.5 由于money是salary的别名,代表同一个对象,也就是money与salary重合在一起﹐所以指令──
money.amount = money.amount + 100相当于── salary.amount = salary.amount + 100 使得 money与salary对象之内容皆变成 2600.5 。
change()程序的定义如下﹕
于是change() 把 money之参考值传回Form1_Click()。此刻﹐change(salary)之值也是参考值,与money参考到同一个对象。
此程序之各项资料皆靠参考值传递。
使得 money、change(salary)及 x皆为salary之别名﹐它们和salary皆参考到同一个对象。
这就参考传递的奇妙景象。现在﹐请看看下述程序﹐藉之深入了解参考传递法了。‘ex12.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
‘------------------------------------------------------------------
Public Class Fee
Public amount As Double
Public Sub New(ByVal amt As Double)
amount = amt
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
Public Function change(ByVal money As Fee) As Fee
money.amount = money.amount + 100
change = money
End Function
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim salary As New Fee(2500.5)
Dim pay As Fee
pay = change(change(change(salary)))
MessageBox.Show("x=" + str(pay.amount) + " salary="
+ str(salary.amount))
End Sub
End Class此程序输出如下﹕
x=2800.5 Salary = 2800.5原来的salary值是2500.5。
指令──
首先把salary参考值给change()程序的money参数。 此程序回传之后﹐change(salary)值等于salary值﹐皆参考到同一个对象,此对象之内容被更新为2600.5了。
于是﹐指令──
呼叫一次change()之后,
就相当于──
再度把salary之参考值传给 money变量﹐再传回后﹐将salary对象内容更新为──2700.5。
就相当于──
其余可依此类推了。了解执行过程和各变量值之后﹔可谓已了解参考值之应用了﹐也了解如何传回对象之参考值了。n
都说VB7模仿java,c++。但是c++,c#有很多借鉴vb的一方。学会了VB7,在VS.Net的集成环境中再学C++,C#相对容易一些,而且可以使用三种语言共同完成一个工作(这是VS.Net最令我服的)。
人用VB6写软件有一些时日了,但是我打算在短时间内不写软件。我相信在一两年后VB7会成为很重要的了。一两年全心的投入对于一门语言来说实在不算多。
我的废话太多了。因为网址有记得,所以贴上一些文章,答谢网友了