|
请注意 ...... 著作权所有人:物泽计算机事业股份有限公司、 MISOO对象技术顾问团队、对象导向杂志作者、等。 u本文件摘自 对象导向杂志、精通对象观念与技术等书籍著作。 u本文件仅供您的参阅,请遵守著作权法,不得做其它商业用途。
主题: 母子对象关系 副题: Whole-Part关系
?????? 内容 ?????? v 1. 特殊Whole-Part关系 ---- 母子对象关系 v 2. 母子对象谁先诞生﹖ v 3. 类别继承与母子对象
1. 特殊Whole-Part关系 ---- 母子对象关系
大家已经熟悉父子类别关系﹐也就是「继承」关系了。于此说明另一种常见关系── 母子对象。一般称之为「组合/部分」关系。日常生活中﹐处处可见到这种母子对象。例如﹐客厅内有沙发、桌子、椅子等等。客厅是母对象﹐沙发、桌子、椅子是子对象。再如计算机屏幕上的窗口内有按钮、选择表、对话盒等等。窗口是母对象﹐按钮、选择表是子对象。于此将说明如何建立母子对象关系。有了关系﹐母子就能互相沟通了。母子对象之间﹐如何沟通呢﹖也就是说﹐母对象如何呼叫子对象的程序呢﹖反过来﹐子对象如何呼叫母对象的程序呢﹖欲呼叫对方的程序﹐必先与对方建立关系才行。因之﹐如何建立母子对象关系﹐是顶重要之课题﹗ 请先看个例子﹐有两个类别──Room和Desk。若Room代表房间﹐Desk代表房间内的桌子﹐则它们会诞生母子对象﹕
通常﹐您会依房间的大小来决定桌子的大小。因之﹐Desk对象应跟Room对象沟通﹐取得房间的大小﹐才决定自己的大小。若有个Room之参考﹐则Desk对象就能跟Room对象沟通了。于是﹐可设计下述VB程序:
''''ex01.bas Imports System.ComponentModel Imports System.Drawing Imports System.WinForms ''''---------------------------------------------------- Class Room Protected rSize As Double Shared motherObject As Room
Public Sub New() motherObject = Me End Sub Shared Function GetMother() As Room GetMother = motherObject End Function Public Function GetSize() As Double GetSize = rSize End Function End Class
Class Desk Protected dSize As Double Public Sub New() dSize = Room.GetMother().GetSize() * 0.18 End Sub Public Function GetSize() As Double GetSize = dSize End Function End Class ''''---------------------------------------------------- Class MyRoom Inherits Room Private rd As Desk Public Sub New() rSize = 100 rd = New Desk() End Sub Public Sub Show() MessageBox.Show("Room Size: " + str(rSize)) MessageBox.Show("Desk Size: " + str(rd.GetSize())) 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 r As New MyRoom() r.Show() End Sub End Class
此程序输出: Room Size: 100 Desk Size: 18
Desk类别内之指令── Room.GetMother().GetSize()
就是Desk对象与Room对象之沟通了。MyRoom类别有个rd参考﹐指向子对象﹐如下﹕
母对象经由rd参考来跟子对象沟通。反过来﹐子对象经由Room.GetMother()参考跟母对象沟通。 2. 母子对象谁先诞生﹖ 在VB里﹐有时候子对象比母对象早诞生完成。就像建造房子﹐建到半途﹐改而建造桌子﹐桌子建好了﹐再继续把房子建完成。由于这不太合乎人们的日常生活习惯﹐令人感到困惑﹗在计算机软件上﹐也有类似的冲突。例如﹐在Windows 下﹐母窗口建好了﹐才建立窗内的按钮、选择表等子对象。但VB有时并非如此﹗因之﹐如何化解这冲突﹐是个重要的话题。兹拿上小节的例子来说明吧﹗该例子中﹐其诞生对象之过程为﹕ Step 1: 先诞生母对象。 Step 2: 接着建立子对象。
这过程合乎人们的习惯﹐是美好的。其原因是﹕MyRoom类别在其建构者New()程序里呼叫Desk的New()诞生Desk子对象。假若您写下述程序﹐就出问题了﹗
''''ex02.bas ''''Some error here! Imports System.ComponentModel Imports System.Drawing Imports System.WinForms ''''---------------------------------------------------- Class Room Protected rSize As Double Shared motherObject As Room
Public Sub New() motherObject = Me End Sub Shared Function GetMother() As Room GetMother = motherObject End Function Public Function GetSize() As Double GetSize = rSize End Function End Class
Class Desk Protected dSize As Double Public Sub New() dSize = Room.GetMother().GetSize() * 0.18 End Sub Public Function GetSize() As Double GetSize = dSize End Function End Class ''''---------------------------------------------------- Class MyRoom Inherits Room Private rd As New Desk() Public Sub New() rSize = 100 End Sub Public Sub Show() MessageBox.Show("Room Size: " + str(rSize)) MessageBox.Show("Desk Size: " + str(rd.GetSize())) 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 r As New MyRoom() r.Show() End Sub End Class
其对象之建造过程为﹕ Step 1: 指令── Dim r As New MyRoom() 呼叫MyRoom()建构者New()。它再呼叫Room()建构者New()将Room部分建好。
Step 2: 执行指令── Private rd As New Desk() 呼叫Desk建构者New()﹐建好Desk子对象。此时会执行指令── dSize = Room.GetMother().GetSize() * 0.18
Step 3: MyRoom建构者New() 继续将母对象建完成。 此时会执行指令── rSize=100 其中,GetSize()程序会取出rSize 值﹐但那时还未执行rSize=100 指令﹐那来 的rSize 值呢﹖所以出问题了。此程序可能输出如下错误结果﹕ Room Size: 100 Desk Size: 0 如何解决上述问题呢﹖常见方法是﹕
把会出问题的指令﹐从建构者程序中提出来﹐放到另一程序里。
例如下述程序:
''''ex03.bas Imports System.ComponentModel Imports System.Drawing Imports Syste [1] [2] [3] [4] 下一页 |