VB.Net中文教程(1) 類別與封裝性 (轉)
請注意 ......
著作權所有人:物澤事業股份有限公司、
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.s
'----------------------------------------------------
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 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 , 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 Class
Form1_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 Class
Tree類別包含 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
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988984/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- VB.Net中文教程(3) 繼承與封裝性 (轉)繼承封裝
- VB.Net中文教程(4) 類別繼承(Inheritance)關係 (轉)繼承
- 一、類的封裝性封裝
- VB.Net中文教程(11) Prototype樣式 (轉)
- VB.Net中文教程(2) Composite樣式 (轉)
- VB.Net中文教程(7) Me參考值 (轉)
- VB.Net中文教程(5)程式多重定義 (轉)
- VB.Net中文教程(6) 母子物件關係 (轉)物件
- VB.Net中文教程(13) Whole-Part關係 (轉)
- 十五、類與封裝的概念封裝
- VB.Net中文教程(9) 重新定義(Overriding)程式 (轉)
- 15_類與封裝的概念封裝
- Flutter Dio 親媽級別封裝教程Flutter封裝
- 封裝xunsearch類封裝
- JS 封裝類JS封裝
- 精通ASP.NET(基於VB.NET)( 二)VB.NET類 (轉)ASP.NET
- Sqlite封裝1-基本封裝-SqliteToolSQLite封裝
- 走近VB.Net(四) 關於資料型別與示例 (轉)資料型別
- 封裝Date工具類封裝
- JsonValue 封裝類JSON封裝
- 封裝Redis工具類封裝Redis
- 原始型別與包裝類型別
- 直播電商平臺開發,日期與時間戳轉換封裝工具類時間戳封裝
- c#封裝DBHelper類C#封裝
- 4、類和物件—封裝物件封裝
- 自用驗證類封裝封裝
- 封裝獲取Class類封裝
- php的curl封裝類PHP封裝
- 封裝JDBC—非框架開發必備的封裝類封裝JDBC框架
- c# Lambda操作類封裝C#封裝
- Android Logcat 封裝類AndroidGC封裝
- http通訊類的封裝HTTP封裝
- Java提高篇(1)封裝Java封裝
- 1_websocket工具封裝Web封裝
- 芥子須彌----封裝 (轉)封裝
- 圖靈假說70年:兩類AI與封閉性挑戰圖靈AI
- 封裝ADO訪問資料庫的兩個類 (轉)封裝資料庫
- Java™ 教程(區域性類)Java