<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # Visual Basic 中的面向對象編程 II > 原文: [https://zetcode.com/lang/visualbasic/oopii/](https://zetcode.com/lang/visualbasic/oopii/) 在 Visual Basic 教程的這一章中,我們將繼續以 Visual Basic 語言描述 OOP。 ## 接口 遙控器是觀眾和電視之間的接口。 它是此電子設備的接口。 外交禮儀指導外交領域的所有活動。 道路規則是駕車者,騎自行車者和行人必須遵守的規則。 編程中的接口類似于前面的示例。 接口是: * API * 合約 對象通過這些方法與外界交互。 實際的實現對程序員而言并不重要,或者也可能是秘密的。 公司可能會出售圖書館,但它不想透露實際的實現情況。 程序員可能會在 GUI 工具箱的窗口中調用`Maximize`方法,但對如何實現此方法一無所知。 從這個角度來看,接口是一種方法,通過這些方法,對象可以與外界交互,而不會過多地暴露其內部工作原理。 從第二個角度來看,接口就是契約。 如果達成協議,則必須遵循。 它們用于設計應用的架構。 他們幫助組織代碼。 接口是完全抽象的類型。 它們使用`Interface`關鍵字聲明。 接口只能具有方法簽名和常量。 接口中聲明的所有方法簽名必須是公共的。 他們不能具有完全實現的方法,也不能具有成員字段。 Visual Basic 類可以實現任何數量的接口。 一個接口還可以擴展任何數量的接口。 實現接口的類必須實現接口的所有方法簽名。 接口用于模擬多重繼承。 Visual Basic 類只能從一個類繼承。 Visual Basic 類可以實現多個接口。 使用接口的多重繼承與繼承方法和變量無關。 它是關于繼承想法或合同的,這些想法或合同由接口描述。 接口和抽象類之間有一個重要的區別。 抽象類為繼承層次結構中相關的類提供部分實現。 另一方面,可以通過彼此不相關的類來實現接口。 例如,我們有兩個按鈕。 經典按鈕和圓形按鈕。 兩者都繼承自抽象按鈕類,該類為所有按鈕提供了一些通用功能。 實現類是相關的,因為它們都是按鈕。 另一個示例可能具有類`Database`和`SignIn`。 它們彼此無關。 我們可以應用`ILoggable`接口,該接口將迫使他們創建執行日志記錄的方法。 ```vb Option Strict On Module Example Interface IInfo Sub DoInform() End Interface Class Some Implements IInfo Sub DoInform() Implements IInfo.DoInform Console.WriteLine("This is Some Class") End Sub End Class Sub Main() Dim sm As New Some sm.DoInform() End Sub End Module ``` 這是一個演示接口的簡單 Visual Basic 程序。 ```vb Interface IInfo Sub DoInform() End Interface ``` 這是接口`IInfo`。 它具有`DoInform()`方法簽名。 ```vb Class Some Implements IInfo ``` 我們使用`Implements`從接口實現。 ```vb Sub DoInform() Implements IInfo.DoInform Console.WriteLine("This is Some Class") End Sub ``` 該類提供了`DoInform()`方法的實現。 `Implements`關鍵字明確指定了我們正在實現的方法簽名。 下一個示例顯示了一個類如何實現多個接口。 ```vb Option Strict On Module Example Interface Device Sub SwitchOn() Sub SwitchOff() End Interface Interface Volume Sub VolumeUp() Sub VolumeDown() End Interface Interface Pluggable Sub PlugIn() Sub PlugOff() End Interface Class CellPhone Implements Device, Volume, Pluggable Public Sub SwitchOn() Implements Device.SwitchOn Console.WriteLine("Switching on") End Sub Public Sub SwitchOff() Implements Device.SwitchOff Console.WriteLine("Switching on") End Sub Public Sub VolumeUp() Implements Volume.VolumeUp Console.WriteLine("Volume up") End Sub Public Sub VolumeDown() Implements Volume.VolumeDown Console.WriteLine("Volume down") End Sub Public Sub PlugIn() Implements Pluggable.PlugIn Console.WriteLine("Plugging In") End Sub Public Sub PlugOff() Implements Pluggable.PlugOff Console.WriteLine("Plugging Off") End Sub End Class Sub Main() Dim o As New CellPhone o.SwitchOn() o.VolumeUp() o.PlugIn() End Sub End Module ``` 我們有一個`CellPhone`類,它從三個接口繼承。 ```vb Class CellPhone Implements Device, Volume, Pluggable ``` 該類實現所有三個接口,并用逗號分隔。 `CellPhone`類必須實現來自所有三個接口的所有方法簽名。 ```vb $ ./interface.exe Switching on Volume up Plugging In ``` 運行程序。 下一個示例顯示接口如何從多個其他接口繼承。 ```vb Option Strict On Module Example Interface IInfo Sub DoInform() End Interface Interface IVersion Sub GetVersion() End Interface Interface ILog Inherits IInfo, IVersion Sub DoLog End Interface Class DBConnect Implements ILog Public Sub DoInform() Implements IInfo.DoInform Console.WriteLine("This is DBConnect class") End Sub Public Sub GetVersion() Implements IVersion.GetVersion Console.WriteLine("Version 1.02") End Sub Public Sub DoLog() Implements ILog.DoLog Console.WriteLine("Logging") End Sub Public Sub Connect() Console.WriteLine("Connecting to the database") End Sub End Class Sub Main() Dim db As New DBConnect db.DoInform() db.GetVersion() db.DoLog() db.Connect() End Sub End Module ``` 我們定義了三個接口。 我們可以按層次組織接口。 ```vb Interface ILog Inherits IInfo, IVersion ``` `ILog`接口繼承自其他兩個接口。 ```vb Public Sub DoInform() Implements IInfo.DoInform Console.WriteLine("This is DBConnect class") End Sub ``` `DBConnect`類實現`DoInform()`方法。 該方法由該類實現的`ILog`接口繼承。 ```vb $ ./interface2.exe This is DBConnect class Version 1.02 Logging Connecting to the database ``` 輸出。 ## 多態 多態是以不同方式將運算符或函數用于不同數據輸入的過程。 實際上,多態意味著如果類`B`從類`A`繼承,則不必繼承關于類`A`的所有內容; 它可以完成`A`類所做的某些事情。 (維基百科) 通常,多態是以不同形式出現的能力。 從技術上講,它是重新定義派生類的方法的能力。 多態與將特定實現應用于接口或更通用的基類有關。 多態是重新定義派生類的方法的能力。 ```vb Option Strict On Module Example MustInherit Class Shape Protected x As Integer Protected y As Integer Public MustOverride Function Area() As Integer End Class Class Rectangle Inherits Shape Sub New(ByVal x As Integer, ByVal y As Integer) Me.x = x Me.y = y End Sub Public Overrides Function Area() As Integer Return Me.x * Me.y End Function End Class Class Square Inherits Shape Sub New(ByVal x As Integer) Me.x = x End Sub Public Overrides Function Area() As Integer Return Me.x * Me.x End Function End Class Sub Main() Dim shapes() As Shape = { New Square(5), _ New Rectangle(9, 4), New Square(12) } For Each shape As Shape In shapes Console.WriteLine(shape.Area()) Next End Sub End Module ``` 在上面的程序中,我們有一個抽象的`Shape`類。 該類變形為兩個后代類,即`Rectangle`和`Square`。 兩者都提供了自己的`Area()`方法的實現。 多態為 OOP 系統帶來了靈活性和可伸縮性。 ```vb Public Overrides Function Area() As Integer Return Me.x * Me.y End Function ... Public Overrides Function Area() As Integer Return Me.x * Me.x End Function ``` `Rectangle`和`Square`類具有`Area`方法的自己的實現。 ```vb Dim shapes() As Shape = { New Square(5), _ New Rectangle(9, 4), New Square(12) } ``` 我們創建三個形狀的數組。 ```vb For Each shape As Shape In shapes Console.WriteLine(shape.Area()) Next ``` 我們遍歷每個形狀并在其上調用`Area`方法。 編譯器為每種形狀調用正確的方法。 這就是多態的本質。 ## `NotOverridable`,`NotInheritable` `NotOverridable`方法不能被覆蓋,`NotInheritable`類不能從中繼承。 這些關鍵字與應用設計有關。 我們不應從某些類繼承,并且不應重寫某些方法。 ```vb Option Strict On Module Example Class Base Public NotOverridable Sub Say() Console.WriteLine("Base class") End Sub End Class Class Derived Inherits Base Public Overrides Sub Say() Console.WriteLine("Derived class") End Sub End Class Sub Main() Dim o As Base = New Derived o.Say() End Sub End Module ``` 該程序將無法編譯。 我們收到錯誤消息`"Public Overrides Sub Say()"`無法覆蓋`"Public NotOverridable Sub Say()"`,因為它被聲明為`"NotOverridable"`。 ```vb Option Strict On Module Example NotInheritable Class Math Public Shared Function getPI() As Single Return 3.141592 End Function End Class Class DerivedMath Inherits Math Public Sub Say() Console.WriteLine("DerivedMath class") End Sub End Class Sub Main() Dim o As DerivedMath = New DerivedMath o.Say() End Sub End Module ``` 在上面的程序中,我們有一個原型基礎`Math`類。 該類的唯一目的是為程序員提供一些有用的方法和常量。 (出于簡單起見,在我們的案例中,我們只有一種方法。)它不是從繼承而創建的。 為了防止不知情的其他程序員從此類中派生,創建者創建了`NotInheritable`類。 如果嘗試編譯該程序,則會出現以下錯誤:'DerivedMath'無法從類'Math'繼承,因為'Math'被聲明為'NotInheritable'。 ## 深拷貝與淺拷貝 數據復制是編程中的重要任務。 對象是 OOP 中的復合數據類型。 對象中的成員字段可以按值或按引用存儲。 可以以兩種方式執行復制。 淺表副本將所有值和引用復制到新實例中。 引用所指向的數據不會被復制; 僅指針被復制。 新的引用指向原始對象。 對引用成員的任何更改都會影響兩個對象。 深層副本將所有值復制到新實例中。 如果成員存儲為引用,則深層副本將對正在引用的數據執行深層副本。 創建一個引用對象的新副本。 并存儲指向新創建對象的指針。 對這些引用對象的任何更改都不會影響該對象的其他副本。 深拷貝是完全復制的對象。 如果成員字段是值類型,則將對該字段進行逐位復制。 如果該字段是引用類型,則復制引用,但不是復制引用的對象。 因此,原始對象中的引用和克隆對象中的引用指向同一對象。 (來自 programmingcorner.blogspot.com 的明確解釋) 接下來的兩個示例將對對象執行淺表復制和深表復制。 ```vb Option Strict On Module Example Class Color Public red as Byte Public green as Byte Public blue as Byte Sub New(red As Byte, green As Byte, _ blue As Byte) Me.red = red Me.green = green Me.blue = blue End Sub End Class Class MyObject Implements ICloneable Public Id As Integer Public Size As String Public Col As Color Sub New(Id As Integer, Size As String, _ Col As Color) Me.Id = Id Me.Size = Size Me.Col = Col End Sub Public Function Clone() As Object _ Implements ICloneable.Clone Return New MyObject(Me.Id, Me.Size, Me.Col) End Function Public Overrides Function ToString() As String Dim s As String s = String.Format("Id: {0}, Size: {1}, Color:({2}, {3}, {4})", _ Me.Id, Me.Size, Me.Col.red, Me.Col.green, Me.Col.blue) Return s End Function End Class Sub Main() Dim col As New Color(23, 42, 223) Dim obj1 As New MyObject(23, "small", col) Dim obj2 As MyObject obj2 = CType(obj1.Clone(), MyObject) obj2.Id += 1 obj2.Size = "big" obj2.Col.red = 255 Console.WriteLine(obj1) Console.WriteLine(obj2) End Sub End Module ``` 這是一個淺表副本的示例。 我們定義了兩個自定義對象:`MyObject`和`Color`。 `MyObject`對象將具有對`Color`對象的引用。 ```vb Class MyObject Implements ICloneable ``` 我們應該為要克隆的對象實現`ICloneable`接口。 ```vb Public Function Clone() As Object _ Implements ICloneable.Clone Return New MyObject(Me.Id, Me.Size, Me.Col) End Function ``` `ICloneable`接口迫使我們創建`Clone()`方法。 此方法返回具有復制值的新對象。 ```vb Dim col As New Color(23, 42, 223) ``` 我們創建`Color`對象的實例。 ```vb Dim obj1 As New MyObject(23, "small", col) ``` 創建`MyObject`對象的實例。 它將`Color`對象的實例傳遞給其構造器。 ```vb obj2 = CType(obj1.Clone(), MyObject) ``` 我們創建`obj1`對象的淺表副本,并將其分配給`obj2`變量。 `Clone()`方法返回`Object`,我們期望`MyObject`。 這就是我們進行顯式轉換的原因。 ```vb obj2.Id += 1 obj2.Size = "big" obj2.Col.red = 255 ``` 在這里,我們修改復制對象的成員字段。 我們增加`Id`,將`Size`更改為`"big"`,然后更改顏色對象的紅色部分。 ```vb Console.WriteLine(obj1) Console.WriteLine(obj2) ``` `Console.WriteLine()`方法調用`obj2`對象的`ToString()`方法,該方法返回對象的字符串表示形式。 ```vb Id: 23, Size: small, Color:(255, 42, 223) Id: 24, Size: big, Color:(255, 42, 223) ``` 我們可以看到 ID 分別為 23 和 24。大小不同。 `small`和`big`。 但是,這兩個實例的顏色對象的紅色部分相同:255。更改克隆對象的成員值(`Id`,`Size`)不會影響原始對象。 更改引用對象(`Col`)的成員也影響了原始對象。 換句話說,兩個對象都引用內存中的同一顏色對象。 要更改此行為,我們接下來將做一個深層復制。 ```vb Option Strict On Module Example Class Color Implements ICloneable Public Red as Byte Public Green as Byte Public Blue as Byte Sub New(Red As Byte, Green As Byte, _ Blue As Byte) Me.Red = Red Me.Green = Green Me.Blue = Blue End Sub Public Function Clone() As Object _ Implements ICloneable.Clone Return New Color(Me.Red, Me.Green, Me.Blue) End Function End Class Class MyObject Implements ICloneable Public Id As Integer Public Size As String Public Col As Color Sub New(Id As Integer, Size As String, _ Col As Color) Me.Id = Id Me.Size = Size Me.Col = Col End Sub Public Function Clone() As Object _ Implements ICloneable.Clone Return New MyObject(Me.Id, Me.Size, CType(Me.Col.Clone(), Color)) End Function Public Overrides Function ToString() As String Dim s As String s = String.Format("Id: {0}, Size: {1}, Color:({2}, {3}, {4})", _ Me.Id, Me.Size, Me.Col.Red, Me.Col.Green, Me.Col.Blue) Return s End Function End Class Sub Main() Dim col As New Color(23, 42, 223) Dim obj1 As New MyObject(23, "small", col) Dim obj2 As MyObject obj2 = CType(obj1.Clone(), MyObject) obj2.Id += 1 obj2.Size = "big" obj2.Col.Red = 255 Console.WriteLine(obj1) Console.WriteLine(obj2) End Sub End Module ``` 在此程序中,我們對對象執行深層復制。 ```vb Class Color Implements ICloneable ``` 現在`Color`類實現了`ICloneable`接口。 ```vb Public Function Clone() As Object _ Implements ICloneable.Clone Return New Color(Me.Red, Me.Green, Me.Blue) End Function ``` 我們也為`Color`類提供了`Clone()`方法。 這有助于創建引用對象的副本。 ```vb Public Function Clone() As Object _ Implements ICloneable.Clone Return New MyObject(Me.Id, Me.Size, CType(Me.Col.Clone(), Color)) End Function ``` 現在,當我們克隆`MyObject`時,我們以`Col`引用類型調用`Clone()`方法。 這樣,我們也可以獲得顏色值的副本。 ```vb $ ./deepcopy.exe Id: 23, Size: small, Color:(23, 42, 223) Id: 24, Size: big, Color:(255, 42, 223) ``` 現在,引用的`Color`對象的紅色部分不相同。 原始對象保留了其先前的 23 值。 ## 異常 異常是為處理異常的發生而設計的,這些特殊情況會改變程序執行的正常流程。 引發或引發異常。 在執行應用期間,許多事情可能出錯。 磁盤可能已滿,我們無法保存文件。 互聯網連接可能斷開,我們的應用嘗試連接到站點。 所有這些都可能導致我們的應用崩潰。 為避免發生這種情況,我們必須應對可能發生的所有可能的錯誤。 為此,我們可以使用異常處理。 `Try`,`Catch`和`Finally`關鍵字用于處理異常。 ```vb Option Strict On Module Example Sub Main() Dim x As Integer = 100 Dim y As Integer = 0 Dim z As Double Try z = x \ y Catch e As Exception Console.WriteLine(e.Message) End Try End Sub End Module ``` 在上面的程序中,我們有意將數字除以零。 這會導致錯誤。 ```vb Try z = x \ y ... End Try ``` 容易出錯的語句放在`Try`關鍵字之后。 ```vb Catch e As Exception Console.WriteLine(e.Message) ... ``` 異常類型跟隨`Catch`關鍵字。 在我們的例子中,我們有一個通用的`Exception`,它將捕獲任何類型的異常。 有一些通用的異常,還有一些更具體的異常。 發生錯誤時,將執行`Catch`關鍵字后面的語句。 發生異常時,將創建一個異常對象。 從該對象中,我們獲得`Message`屬性并將其打印到控制臺。 當前上下文中任何未捕獲的異常都會傳播到更高的上下文,并尋找適當的 `catch`塊來處理它。 如果找不到任何合適的`catch`塊,則 .NET 運行時的默認機制將終止整個程序的執行。 ```vb Option Strict On Module Example Sub Main() Dim z As Double Dim x As Integer = 100 Dim y As Integer = 0 z = x \ y End Sub End Module ``` 在此程序中,我們除以零。 我們沒有自定義異常處理。 在 Visual Basic 2008 Express 上,我們收到以下錯誤消息:“未處理的異常:`System.DivideByZeroException`:試圖除以零。”。 ```vb Option Strict On Imports System.IO Module Example Dim fs As FileStream Sub Main() Try fs = File.Open("file", FileMode.OpenOrCreate) Console.WriteLine(fs.Length) Catch e As IOException Console.WriteLine("IO Error") Console.WriteLine(e.Message) Finally Console.WriteLine("Finally") If fs.CanRead = True Then fs.Close() End If End Try End Sub End Module ``` 始終執行`Finally`關鍵字之后的語句。 它通常用于清理任務,例如關閉文件或清除緩沖區。 ```vb Catch e As IOException Console.WriteLine("IO Error") Console.WriteLine(e.Message) ``` 在這種情況下,我們捕獲了特定的`IOException`異常。 ```vb Finally Console.WriteLine("Finally") If fs.CanRead = True Then fs.Close() End If ``` 這些行確保關閉文件處理器。 ```vb Option Strict On Module Example Sub Main() Dim x As Integer Dim y As Integer Dim z As Double Try Console.Write("Enter first number: ") x = Convert.ToInt32(Console.ReadLine()) Console.Write("Enter second number: ") y = Convert.ToInt32(Console.ReadLine()) z = x / y Console.WriteLine("Result: {0:D} / {1:D} = {2:D}", x, y, z) Catch e As DivideByZeroException Console.WriteLine("Cannot divide by zero.") Catch e As FormatException Console.WriteLine("Wrong format of number.") Catch e As Exception Console.WriteLine(e.Message) End Try End Sub End Module ``` 在此示例中,我們捕獲了各種異常。 請注意,更具體的異常應先于一般的異常。 我們從控制臺讀取兩個數字,并檢查零除錯誤和數字格式錯誤。 ```vb $ ./passing.exe Enter first number: et Wrong format of number. ``` 運行示例。 ```vb Option Strict On Module Example Class BigValueException Inherits Exception Sub New(ByVal msg As String) MyBase.New(msg) End Sub End Class Sub Main() Dim x As Integer = 340004 Const LIMIT As Integer = 333 Try If (x > LIMIT) Then Throw New BigValueException("Exceeded the maximum value") End If Catch e As BigValueException Console.WriteLine(e.Message) End Try End Sub End Module ``` 假設我們處于無法處理大量數字的情況。 ```vb Class BigValueException Inherits Exception ``` 我們有一個`BigValueException`類。 該類派生自內置的`Exception`類。 ```vb Dim Const LIMIT As Integer = 333 ``` 大于此常數的數字在我們的程序中被視為`big`。 ```vb Sub New(ByVal msg As String) MyBase.New(msg) End Sub ``` 在構造器內部,我們稱為父級的構造器。 我們將消息傳遞給父級。 ```vb If (x > LIMIT) Then Throw New BigValueException("Exceeded the maximum value") End If ``` 如果該值大于限制,則拋出自定義異常。 我們給異常消息`"Exceeded the maximum value"`。 ```vb Catch e As BigValueException Console.WriteLine(e.Message) ``` 我們捕獲到異常并將其消息打印到控制臺。 ## 屬性 屬性是特殊的類成員。 我們使用預定義的設置和獲取方法來訪問和修改它們。 屬性讀取和寫入會轉換為獲取和設置方法調用。 與使用自定義方法調用(例如`object.GetName()`)相比,使用字段符號(例如`object.Name`)訪問變量更容易。 但是,就屬性而言,我們仍然具有封裝和信息隱藏的優勢。 ```vb Option Strict On Module Example Class Person Private _name As String Public Property Name() As String Get Return _name End Get Set (Byval Value As String) _name = Value End Set End Property End Class Sub Main() Dim p as New Person p.Name = "Jane" Console.WriteLine(p.Name()) End Sub End Module ``` 我們有一個帶有一個屬性的簡單`Person`類。 ```vb Public Property Name() As String ... End Property ``` 我們使用`Property`關鍵字在 Visual Basic 中創建屬性。 ```vb Get Return _name End Get ``` 我們使用預定義的`Get`關鍵字為`_name`字段創建訪問器方法。 ```vb Set (Byval Value As String) _name = Value End Set ``` 類似地,`Set`關鍵字為`_name`字段創建一個修改器方法。 ```vb Dim p as New Person p.Name = "Jane" Console.WriteLine(p.Name()) ``` 我們創建`Person`類的實例。 我們使用字段符號訪問成員字段。 ```vb $ ./properties.exe Jane ``` 這是該計劃的結果。 ## 委托 委托是 .NET Framework 使用的一種類型安全的函數指針。 委托通常用于實現回調和事件監聽器。 ```vb Option Strict On Module Example Public Delegate Sub NameDelegate(ByVal msg As String) Class Person Private FirstName As String Private SecondName As String Sub New(First As String, Second As String) Me.FirstName = First Me.SecondName = Second End Sub Public Sub ShowFirstName(msg As String) Console.WriteLine(msg & Me.FirstName) End Sub Public Sub ShowSecondName(msg As String) Console.WriteLine(msg & Me.SecondName) End Sub End Class Sub Main() Dim nDelegate As NameDelegate Dim per As New Person("Fabius", "Maximus") nDelegate = AddressOf per.ShowFirstName nDelegate("Call 1: ") nDelegate = AddressOf per.ShowSecondName nDelegate("Call 2: ") End Sub End Module ``` 在此示例中,我們只有一名委托。 該委托用于指向`Person`類的兩個方法。 方法與委托一起調用。 ```vb Public Delegate Sub NameDelegate(ByVal msg As String) ``` 使用`Delegate`關鍵字創建委托。 委托簽名必須與委托調用的方法的簽名匹配。 ```vb Dim nDelegate As NameDelegate ``` 在這里,我們創建一個自定義委托類型的變量。 ```vb nDelegate = AddressOf per.ShowFirstName nDelegate("Call 1: ") ``` `AddressOf`運算符用于獲取對`ShowFirstName(`方法的引用。 現在我們指向該方法,我們可以通過委托來調用它。 ```vb $ ./simpledelegate.exe Call 1: Fabius Call 2: Maximus ``` 這兩個名稱都是通過委托打印的。 ## 事件 事件是由某些操作觸發的消息。 點擊按鈕或時鐘的滴答聲就是這樣的動作。 觸發事件的對象稱為發送者,而接收事件的對象稱為接收者。 ```vb Option Strict On Module Example Public Event ValueFive() Dim Random As Integer Public Sub Main() AddHandler ValueFive, AddressOf OnFiveEvent For i As Integer = 0 To 10 Randomize() Random = CInt(Rnd() * 7) Console.WriteLine(Random) If Random = 5 Then RaiseEvent ValueFive() End If Next End Sub Public Sub OnFiveEvent() Console.WriteLine("Five Event occured") End Sub End Module ``` 我們有一個簡單的示例,可以在其中創建和啟動事件。 生成一個隨機數。 如果數字等于 5,則會生成`FiveEvent`事件。 ```vb Public Event ValueFive() ``` 使用`Event`關鍵字聲明事件。 ```vb AddHandler ValueFive, AddressOf OnFiveEvent ``` 在這里,我們將名為`ValueFive()`的事件插入`OnFiveEvent()`子例程。 換句話說,如果觸發了`ValueFive`事件,則將執行`OnFiveEvent()`子例程。 ```vb If Random = 5 Then RaiseEvent ValueFive() End If ``` 當隨機數等于 5 時,我們引發`ValueFive`事件。 我們使用`RaiseEvent`關鍵字。 ```vb $ ./event.exe 0 1 5 Five Event occured 2 5 Five Event occured 6 7 6 3 3 1 ``` 該程序的結果可能如下所示。 接下來,我們有一個更復雜的示例。 ```vb Option Strict On Namespace EventSample Public Class FiveEventArgs Inherits EventArgs Public Count As Integer Public Time As Date Public Sub New(ByVal Count As Integer, ByVal Time As Date) Me.Count = Count Me.Time = Time End Sub End Class Public Class Five Private Count As Integer = 0 Public Sub OnFiveEvent(ByVal source As Object, _ ByVal e As FiveEventArgs) Console.WriteLine("Five event {0} occured at {1}", _ e.Count, e.Time) End Sub End Class Public Class RandomGenerator Public Event ValueFive(ByVal source As Object, _ ByVal e As FiveEventArgs) Public Sub Generate() Dim Count As Integer = 0 Dim args As FiveEventArgs For i As Byte = 0 To 10 Dim Random As Integer Randomize() Random = CInt(Rnd * 6) Console.WriteLine(Random) If Random = 5 Then Count += 1 args = New FiveEventArgs(Count, Now) RaiseEvent ValueFive(Me, args) End If Next End Sub End Class Public Class Example Public Shared Sub Main() Dim five As New Five Dim gen As New RandomGenerator AddHandler gen.ValueFive, AddressOf five.OnFiveEvent gen.Generate() End Sub End Class End Namespace ``` 我們有四個類。 `FiveEventArgs`隨事件對象一起傳送一些數據。 `Five`類封裝了事件對象。 `RandomGenerator`類負責生成隨機數。 它是事件發送者。 最后是`Example`類,它是主要的應用對象,具有`Main()`方法。 ```vb Public Class FiveEventArgs Inherits EventArgs Public Count As Integer Public Time As Date ... ``` `FiveEventArgs`在事件對象內部傳送數據。 它繼承自`EventArgs`基類。 `Count`和`Time`成員是將被初始化并隨事件攜帶的數據。 ```vb If Random = 5 Then Count += 1 args = New FiveEventArgs(Count, Now) RaiseEvent ValueFive(Me, args) End If ``` 如果生成的隨機數等于 5,我們用當前的`Count`和`Date`值實例化`FiveEventArgs`類。 `Count`變量對生成此事件的次數進行計數。 `Time`值保留事件生成的時間。 使用帶有發送者對象和事件參數的`RaiseEvent`關鍵字發送事件。 ```vb AddHandler gen.ValueFive, AddressOf five.OnFiveEvent ``` 我們將`ValueFive`事件插入其處理器。 ```vb $ ./event2.exe 3 6 5 Five event 1 occured at 9/15/2010 5:06:13 PM 3 5 Five event 2 occured at 9/15/2010 5:06:13 PM 6 3 2 5 Five event 3 occured at 9/15/2010 5:06:13 PM 2 5 Five event 4 occured at 9/15/2010 5:06:13 PM ``` 這是我在計算機上得到的輸出。 在 Visual Basic 教程的這一部分中,我們繼續討論 Visual Basic 中的面向對象編程。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看