# 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 中的面向對象編程。
- ZetCode 數據庫教程
- MySQL 教程
- MySQL 簡介
- MySQL 安裝
- MySQL 的第一步
- MySQL 快速教程
- MySQL 存儲引擎
- MySQL 數據類型
- 在 MySQL 中創建,更改和刪除表
- MySQL 表達式
- 在 MySQL 中插入,更新和刪除數據
- MySQL 中的SELECT語句
- MySQL 子查詢
- MySQL 約束
- 在 MySQL 中導出和導入數據
- 在 MySQL 中連接表
- MySQL 函數
- MySQL 中的視圖
- MySQL 中的事務
- MySQL 存儲過程
- MySQL Python 教程
- MySQL Perl 教程
- MySQL & Perl DBI
- 使用 Perl 連接到 MySQL 數據庫
- MySQL 中的 Perl 錯誤處理
- 使用 Perl 進行 MySQL 查詢
- 在 MySQL 中使用 Perl 綁定參數&列
- 在 MySQL 中使用 Perl 處理圖像
- 使用 Perl 獲取 MySQL 元數據
- Perl 的 MySQL 事務
- MySQL C API 編程教程
- MySQL Visual Basic 教程
- MySQL PHP 教程
- MySQL Java 教程
- MySQL Ruby 教程
- MySQL C# 教程
- SQLite 教程
- SQLite 簡介
- sqlite3 命令行工具
- 在 SQLite 中創建,刪除和更改表
- SQLite 表達式
- SQLite 插入,更新,刪除數據
- SQLite SELECT語句
- SQLite 約束
- SQLite 連接表
- SQLite 函數
- SQLite 視圖,觸發器,事務
- SQLite C 教程
- SQLite Python 教程
- SQLite Perl 教程
- Perl DBI
- 使用 Perl 連接到 SQLite 數據庫
- SQLite Perl 錯誤處理
- 使用 Perl 的 SQLite 查詢
- 使用 Perl 綁定 SQLite 參數&列
- 使用 Perl 在 SQLite 中處理圖像
- 使用 Perl 獲取 SQLite 元數據
- 使用 Perl 進行 SQLite 事務
- SQLite Ruby 教程
- 連接到 SQLite 數據庫
- 在 SQLite 中使用 Ruby 進行 SQL 查詢
- 綁定參數
- 處理圖像
- 使用 Ruby 獲取 SQLite 元數據
- Ruby 的 SQLite 事務
- SQLite C# 教程
- SQLite C# 簡介
- 使用SqliteDataReader檢索數據
- ADO.NET 數據集
- 使用 C# 在 SQLite 中處理圖像
- 使用 C# 獲取 SQLite 元數據
- 使用 C# 的 SQLite 事務
- SQLite Visual Basic 教程
- SQLite Visual Basic 簡介
- 使用SqliteDataReader檢索數據
- ADO.NET 的數據集
- 使用 Visual Basic 在 SQLite 中處理圖像
- 使用 Visual Basic 獲取 SQLite 元數據
- 使用 Visual Basic 的 SQLite 事務
- PostgreSQL C 教程
- PostgreSQL Ruby 教程
- PostgreSQL PHP 教程
- PostgreSQL PHP 編程簡介
- 在 PostgreSQL 中使用 PHP 檢索數據
- 在 PostgreSQL 中使用 PHP 處理圖像
- 用 PHP 獲取 PostgreSQL 元數據
- 在 PostgreSQL 中使用 PHP 進行事務
- PostgreSQL Java 教程
- Apache Derby 教程
- Derby 簡介
- Derby 的安裝&配置
- Derby 工具
- ij 工具
- Derby 中的 SQL 查詢
- 在 Derby 中使用 JDBC 進行編程
- Derby 安全
- 使用 Derby & Apache Tomcat
- NetBeans 和 Derby
- SQLAlchemy 教程
- SQLAlchemy 簡介
- 原始 SQL
- 模式定義語言
- SQL 表達式語言
- SQLAlchemy 中的對象關系映射器
- MongoDB PHP 教程
- MongoDB JavaScript 教程
- MongoDB Ruby 教程
- Spring JdbcTemplate 教程
- JDBI 教程
- MyBatis 教程
- Hibernate Derby 教程
- ZetCode .NET 教程
- Visual Basic 教程
- Visual Basic
- Visual Basic 語法結構
- 基本概念
- Visual Basic 數據類型
- Visual Basic 中的字符串
- 運算符
- 控制流
- Visual Basic 數組
- Visual Basic 中的過程&函數
- 在 Visual Basic 中組織代碼
- 面向對象編程
- Visual Basic 中的面向對象編程 II
- Visual Basic 中的集合
- 輸入和輸出
- C# 教程
- C# 語言
- C# 語法結構
- C# 基礎
- C# 數據類型
- C# 中的字符串
- C# 運算符
- C# 中的流控制
- C# 數組
- C# 面向對象編程
- C# 中的方法
- C# 面向對象編程 II
- C# 屬性
- C# 結構
- C# 委托
- 命名空間
- C# 集合
- C# 輸入和輸出
- C# 目錄教程
- C# 字典教程
- 在 C# 中讀取文本文件
- C# 中的日期和時間
- 在 C# 中讀取網頁
- C# HttpClient教程
- ASP.NET Core 教程
- ZetCode 圖形教程
- Java 2D 游戲教程
- Java 游戲基礎
- 動畫
- 移動精靈
- 碰撞檢測
- Java 益智游戲
- Java Snake
- Breakout 游戲
- Java 俄羅斯方塊
- Java 吃豆人
- Java 太空侵略者
- Java 掃雷
- Java 推箱子
- Java 2D 教程
- 介紹
- 基本繪圖
- 形狀和填充
- 透明度
- 合成
- 剪裁
- 變換
- 特效
- 圖像
- 文字和字體
- 命中測試,移動物體
- 俄羅斯方塊
- Cario 圖形教程
- Cario 圖形庫
- Cario 定義
- Cairo 后端
- Cairo 基本圖形
- 形狀和填充
- 漸變
- 透明度
- 合成
- 剪裁和遮罩
- 變換
- Cairo 文字
- Cairo 中的圖像
- 根窗口
- PyCairo 教程
- PyCairo 簡介
- PyCairo 后端
- PyCairo 中的基本繪圖
- PyCairo 形狀和填充
- PyCairo 漸變
- PyCairo 剪裁&遮罩
- PyCairo 的透明度
- PyCairo 中的變換
- PyCairo 中的文字
- PyCairo 中的圖像
- 根窗口
- HTML5 畫布教程
- 介紹
- HTML5 畫布中的直線
- HTML5 畫布形狀
- HTML5 畫布填充
- HTML5 畫布中的透明度
- HTML5 畫布合成
- HTML5 canvas 中的變換
- HTML5 畫布中的文字
- HTML5 畫布中的動畫
- HTML5 畫布中的 Snake
- ZetCode GUI 教程
- Windows API 教程
- Windows API 簡介
- Windows API main函數
- Windows API 中的系統函數
- Windows API 中的字符串
- Windows API 中的日期和時間
- Windows API 中的一個窗口
- UI 的第一步
- Windows API 菜單
- Windows API 對話框
- Windows API 控件 I
- Windows API 控件 II
- Windows API 控件 III
- Windows API 中的高級控件
- Windows API 中的自定義控件
- Windows API 中的 GDI
- PyQt4 教程
- PyQt4 簡介
- PyQt4 中的第一個程序
- PyQt4 中的菜單和工具欄
- PyQt4 中的布局管理
- PyQt4 中的事件和信號
- PyQt4 中的對話框
- PyQt4 小部件
- PyQt4 小部件 II
- PyQt4 中的拖放
- PyQt4 中的繪圖
- PyQt4 中的自定義小部件
- PyQt4 中的俄羅斯方塊游戲
- PyQt5 教程
- PyQt5 簡介
- PyQt5 日期和時間
- PyQt5 中的第一個程序
- PyQt5 中的菜單和工具欄
- PyQt5 中的布局管理
- PyQt5 中的事件和信號
- PyQt5 中的對話框
- PyQt5 小部件
- PyQt5 小部件 II
- PyQt5 拖放
- PyQt5 中的繪圖
- PyQt5 中的自定義小部件
- PyQt5 中的俄羅斯方塊
- Qt4 教程
- Qt4 工具包簡介
- Qt4 工具類
- Qt4 中的字符串
- Qt4 中的日期和時間
- 在 Qt4 中使用文件和目錄
- Qt4 中的第一個程序
- Qt4 中的菜單和工具欄
- Qt4 中的布局管理
- Qt4 中的事件和信號
- Qt4 小部件
- Qt4 小部件 II
- Qt4 中的繪圖
- Qt4 中的自定義小部件
- Qt4 中的打磚塊游戲
- Qt5 教程
- Qt5 工具包簡介
- Qt5 中的字符串
- Qt5 中的日期和時間
- Qt5 中的容器
- 在 Qt5 中處理文件和目錄
- Qt5 中的第一個程序
- Qt5 中的菜單和工具欄
- Qt5 中的布局管理
- Qt5 中的事件和信號
- Qt5 小部件
- Qt5 小部件 II
- Qt5 中的繪圖
- Qt5 中的自定義小部件
- Qt5 中的貪食蛇
- Qt5 中的打磚塊游戲
- PySide 教程
- PySide 工具包簡介
- PySide 中的第一個程序
- PySide 中的菜單和工具欄
- PySide 中的布局管理
- PySide 中的事件和信號
- PySide 中的對話框
- PySide 小部件
- PySide 小部件 II
- 在 PySide 中拖放
- 在 PySide 中繪圖
- PySide 中的自定義小部件
- PySide 中的俄羅斯方塊游戲
- Tkinter 教程
- Tkinter 簡介
- Tkinter 中的布局管理
- Tkinter 標準小部件屬性
- Tkinter 小部件
- Tkinter 中的菜單和工具欄
- Tkinter 中的對話框
- Tkinter 中的繪圖
- Tkinter 中的貪食蛇
- Tcl/Tk 教程
- Tcl/Tk 簡介
- Tcl/Tk 中的布局管理
- Tcl/Tk 小部件
- Tcl/Tk 中的菜單和工具欄
- Tcl/Tk 中的對話框
- Tcl/Tk 繪圖
- 貪食蛇
- Qt 快速教程
- Java Swing 教程
- Java Swing 簡介
- Java Swing 首個程序
- Java Swing 中的菜單和工具欄
- Swing 布局管理
- GroupLayout管理器
- Java Swing 事件
- 基本的 Swing 組件
- 基本的 Swing 組件 II
- Java Swing 對話框
- Java Swing 模型架構
- Swing 中的拖放
- Swing 中的繪圖
- Java Swing 中的可調整大小的組件
- Java Swing 中的益智游戲
- 俄羅斯方塊
- JavaFX 教程
- JavaFX 簡介
- JavaFX 首個程序
- JavaFX 布局窗格
- 基本的 JavaFX 控件
- 基本 JavaFX 控件 II
- JavaFX 事件
- JavaFX 效果
- JavaFX 動畫
- JavaFX 畫布
- JavaFX 圖表
- Java SWT 教程
- Java SWT 簡介
- Java SWT 中的布局管理
- Java SWT 中的菜單和工具欄
- Java SWT 中的小部件
- Table小部件
- Java SWT 中的對話框
- Java SWT 繪圖
- Java SWT 中的貪食蛇
- wxWidgets 教程
- wxWidgets 簡介
- wxWidgets 助手類
- wxWidgets 中的第一個程序
- wxWidgets 中的菜單和工具欄
- wxWidgets 中的布局管理
- wxWidgets 中的事件
- wxWidgets 中的對話框
- wxWidgets 小部件
- wxWidgets 小部件 II
- wxWidgets 中的拖放
- wxWidgets 中的設備上下文
- wxWidgets 中的自定義小部件
- wxWidgets 中的俄羅斯方塊游戲
- wxPython 教程
- wxPython 簡介
- 第一步
- 菜單和工具欄
- wxPython 中的布局管理
- wxPython 中的事件
- wxPython 對話框
- 小部件
- wxPython 中的高級小部件
- wxPython 中的拖放
- wxPython 圖形
- 創建自定義小部件
- wxPython 中的應用框架
- wxPython 中的俄羅斯方塊游戲
- C# Winforms Mono 教程
- Mono Winforms 簡介
- Mono Winforms 中的第一步
- Mono Winforms 中的布局管理
- Mono Winforms 中的菜單和工具欄
- Mono Winforms 中的基本控件
- Mono Winforms 中的高級控件
- 對話框
- Mono Winforms 中的拖放
- Mono Winforms 中的繪圖
- Mono Winforms 中的貪食蛇
- Java Gnome 教程
- Java Gnome 簡介
- Java Gnome 的第一步
- Java Gnome 中的布局管理
- Java Gnome 中的布局管理 II
- Java Gnome 中的菜單
- Java Gnome 中的工具欄
- Java Gnome 中的事件
- Java Gnome 中的小部件
- Java Gnome 中的小部件 II
- Java Gnome 中的高級小部件
- Java Gnome 中的對話框
- Java Gnome 中的 Pango
- 在 Java Gnome 中用 Cairo 繪圖
- Cario 繪圖 II
- Java Gnome 中的貪食蛇
- QtJambi 教程
- QtJambi 簡介
- QtJambi 中的布局管理
- QtJambi 中的小部件
- QtJambi 中的菜單和工具欄
- QtJambi 對話框
- QtJambi 中的繪圖
- QtJambi 中的自定義小部件
- 貪食蛇
- GTK+ 教程
- GTK+ 簡介
- GTK+ 中的第一個程序
- GTK+ 中的菜單和工具欄
- GTK+ 布局管理
- GTK+ 事件和信號
- GTK+ 對話框
- GTK+ 小部件
- GTK+ 小部件 II
- GtkTreeView小部件
- GtkTextView小部件
- 自定義 GTK+ 小部件
- Ruby GTK 教程
- Ruby GTK 簡介
- Ruby GTK 中的布局管理
- Ruby GTK 中的小部件
- Ruby GTK 中的菜單和工具欄
- Ruby GTK 中的對話框
- Ruby GTK Cario 繪圖
- Ruby GTK 中的自定義小部件
- Ruby GTK 中的貪食蛇
- GTK# 教程
- GTK# 簡介
- GTK 的第一步
- GTK# 中的布局管理
- GTK 中的菜單
- GTK# 中的工具欄
- GTK# 中的事件
- GTK# 中的小部件
- GTK 中的小部件 II
- GTK# 中的高級小部件
- GTK# 中的對話框
- Pango
- GTK# 中的 Cario 繪圖
- GTK# 中的 Cario 繪圖 II
- GTK# 中的自定義小部件
- Visual Basic GTK# 教程
- Visual Basic GTK# 簡介
- 布局管理
- 小部件
- 菜單和工具欄
- 對話框
- Cario 繪圖
- 自定義小部件
- 貪食蛇
- PyGTK 教程
- PyGTK 簡介
- PyGTK 的第一步
- PyGTK 中的布局管理
- PyGTK 中的菜單
- PyGTK 中的工具欄
- PyGTK 中的事件和信號
- PyGTK 中的小部件
- PyGTK 中的小部件 II
- PyGTK 中的高級小部件
- PyGTK 中的對話框
- Pango
- Pango II
- PyGTK 中的 Cario 繪圖
- Cario 繪圖 II
- PyGTK 中的貪食蛇游戲
- PyGTK 中的自定義小部件
- PHP GTK 教程
- PHP GTK 簡介
- PHP GTK 中的布局管理
- PHP GTK 中的小部件
- PHP GTK 中的菜單和工具欄
- 對話框
- Cario 繪圖
- 自定義小部件
- 貪食蛇
- C# Qyoto 教程
- Qyoto 介紹
- 布局管理
- Qyoto 中的小部件
- Qyoto 中的菜單和工具欄
- Qyoto 對話框
- Qyoto 中的繪圖
- Qyoto 中的繪圖 II
- Qyoto 中的自定義小部件
- 貪食蛇
- Ruby Qt 教程
- Ruby Qt 簡介
- Ruby Qt 中的布局管理
- Ruby Qt 中的小部件
- 菜單和工具欄
- Ruby Qt 中的對話框
- 用 Ruby Qt 繪圖
- Ruby Qt 中的自定義小部件
- Ruby Qt 中的貪食蛇
- Visual Basic Qyoto 教程
- Qyoto 介紹
- 布局管理
- Qyoto 中的小部件
- Qyoto 中的菜單和工具欄
- Qyoto 對話框
- Qyoto 中的繪圖
- Qyoto 中的自定義小部件
- 貪食蛇
- Mono IronPython Winforms 教程
- 介紹
- IronPython Mono Winforms 中的第一步
- 布局管理
- 菜單和工具欄
- Mono Winforms 中的基本控件
- Mono Winforms 中的基本控件 II
- Mono Winforms 中的高級控件
- 對話框
- Mono Winforms 中的拖放
- 繪圖
- IronPython Mono Winforms 中的繪圖 II
- IronPython Mono Winforms 中的貪食蛇
- IronPython Mono Winforms 中的俄羅斯方塊游戲
- FreeBASIC GTK 教程
- Jython Swing 教程
- Jython Swing 簡介
- Jython Swing 中的布局管理
- Jython Swing 中的組件
- Jython Swing 中的菜單和工具欄
- Jython Swing 中的對話框
- Jython Swing 中的繪圖
- Jython Swing 中的半字節
- JRuby Swing 教程
- JRuby Swing 簡介
- JRuby Swing 中的布局管理
- JRuby Swing 中的組件
- 菜單和工具欄
- JRuby Swing 中的對話框
- 在 JRuby Swing 中繪圖
- JRuby Swing 中的貪食蛇
- Visual Basic Winforms 教程
- Visual Basic Winforms 簡介
- 布局管理
- 基本控制
- 進階控件
- 菜單和工具欄
- 對話框
- 繪圖
- 拖放
- 貪食蛇
- JavaScript GTK 教程
- JavaScript GTK 簡介
- 布局管理
- JavaScript GTK 中的小部件
- JavaScript GTK 中的菜單和工具欄
- JavaScript GTK 中的對話框
- JavaScript GTK 中的 Cario 繪圖
- ZetCode Java 教程
- Java 教程
- Java 語言
- Java 語法結構
- Java 基礎
- Java 數據類型
- Java 數據類型 II
- Java 字符串
- Java 數組
- Java 表達式
- Java 控制流程
- Java 面向對象的編程
- Java 方法
- Java 面向對象編程 II
- Java 包
- Java 中的異常
- Java 集合
- Java 流
- Java Future 教程
- Java Comparable和Comparator
- Java DOM 教程
- Java MVC 教程
- Java SAX 教程
- Java JAXB 教程
- Java JSON 處理教程
- Java H2 教程
- MongoDB Java 教程
- Java 正則表達式教程
- Java PDFBox 教程
- Java 文件教程
- Java Files.list教程
- Java Files.walk教程
- Java DirectoryStream教程
- Java 外部與內部迭代器
- Java 文件大小
- 用 Java 創建目錄
- 用 Java 創建文件
- Java Log4j 教程
- Gson 教程
- Java RequestDispatcher
- Java HTTP GET/POST 請求
- Java InputStream教程
- Java FileOutputStream教程
- Java FileInputStream教程
- Java ZipInputStream教程
- Java FileWriter教程
- EJB 簡介
- Java forEach教程
- Jetty 教程
- Tomcat Derby 教程
- Stripes 介紹
- 使用 Stripes 的 Java webapp,MyBatis,& Derby
- EclipseLink 簡介
- Java 中的數據源
- JSTL 中的 SQL 查詢標記
- Java 驗證過濾器
- Hibernate 驗證器
- 用 Java 顯示圖像
- Play 框架簡介
- Spark Java 簡介
- Java ResourceBundle教程
- Jtwig 教程
- Java Servlet 教程
- Java 套接字教程
- FreeMarker 教程
- Android 教程
- Java EE 5 教程
- JSoup 教程
- JFreeChart 教程
- ImageIcon教程
- 用 Java 復制文件
- Java 文件時間教程
- 如何使用 Java 獲取當前日期時間
- Java 列出目錄內容
- Java 附加到文件
- Java ArrayList教程
- 用 Java 讀寫 ICO 圖像
- Java int到String的轉換
- Java HashSet教程
- Java HashMap教程
- Java static關鍵字
- Java 中的HashMap迭代
- 用 Java 過濾列表
- 在 Java 中讀取網頁
- Java 控制臺應用
- Java 集合的便利工廠方法
- Google Guava 簡介
- OpenCSV 教程
- 用 Java8 的StringJoiner連接字符串
- Java 中元素迭代的歷史
- Java 謂詞
- Java StringBuilder
- Java 分割字串教學
- Java NumberFormat
- Java TemporalAdjusters教程
- Apache FileUtils教程
- Java Stream 過濾器
- Java 流歸約
- Java 流映射
- Java InputStreamReader教程
- 在 Java 中讀取文本文件
- Java Unix 時間
- Java LocalTime
- Java 斐波那契
- Java ProcessBuilder教程
- Java 11 的新功能
- ZetCode JavaScript 教程
- Ramda 教程
- Lodash 教程
- Collect.js 教程
- Node.js 簡介
- Node HTTP 教程
- Node-config 教程
- Dotenv 教程
- Joi 教程
- Liquid.js 教程
- faker.js 教程
- Handsontable 教程
- PouchDB 教程
- Cheerio 教程
- Axios 教程
- Jest 教程
- JavaScript 正則表達式
- 用 JavaScript 創建對象
- Big.js 教程
- Moment.js 教程
- Day.js 教程
- JavaScript Mustache 教程
- Knex.js 教程
- MongoDB JavaScript 教程
- Sequelize 教程
- Bookshelf.js 教程
- Node Postgres 教程
- Node Sass 教程
- Document.querySelector教程
- Document.all教程
- JSON 服務器教程
- JavaScript 貪食蛇教程
- JavaScript 構建器模式教程
- JavaScript 數組
- XMLHttpRequest教程
- 從 JavaScript 中的 URL 讀取 JSON
- 在 JavaScript 中循環遍歷 JSON 數組
- jQuery 教程
- Google 圖表教程
- ZetCode Kotlin 教程
- Kotlin Hello World 教程
- Kotlin 變量
- Kotlin 的運算符
- Kotlin when表達式
- Kotlin 數組
- Kotlin 范圍
- Kotlin Snake
- Kotlin Swing 教程
- Kotlin 字符串
- Kotlin 列表
- Kotlin 映射
- Kotlin 集合
- Kotlin 控制流程
- Kotlin 寫入文件
- Kotlin 讀取文件教程
- Kotlin 正則表達式
- ZetCode 其它教程
- TCL 教程
- Tcl
- Tcl 語法結構
- Tcl 中的基本命令
- Tcl 中的表達式
- Tcl 中的控制流
- Tcl 中的字符串
- Tcl 列表
- Tcl 中的數組
- Tcl 中的過程
- 輸入&輸出
- AWK 教程
- Vaadin 教程
- Vaadin 框架介紹
- Vaadin Grid教程
- Vaadin TextArea教程
- Vaadin ComboBox教程
- Vaadin Slider教程
- Vaadin CheckBox教程
- Vaadin Button教程
- Vaadin DateField教程
- Vaadin Link教程
- ZetCode PHP 教程
- PHP 教程
- PHP
- PHP 語法結構
- PHP 基礎
- PHP 數據類型
- PHP 字符串
- PHP 運算符
- PHP 中的控制流
- PHP 數組
- PHP 數組函數
- PHP 中的函數
- PHP 正則表達式
- PHP 中的面向對象編程
- PHP 中的面向對象編程 II
- PHP Carbon 教程
- PHP Monolog 教程
- PHP 配置教程
- PHP Faker 教程
- Twig 教程
- Valitron 教程
- Doctrine DBAL QueryBuilder 教程
- PHP Respect 驗證教程
- PHP Rakit 驗證教程
- PHP PDO 教程
- CakePHP 數據庫教程
- PHP SQLite3 教程
- PHP 文件系統函數
- ZetCode Python 教程
- Python 教程
- Python 語言
- 交互式 Python
- Python 語法結構
- Python 數據類型
- Python 字符串
- Python 列表
- Python 字典
- Python 運算符
- Python 關鍵字
- Python 函數
- Python 中的文件
- Python 中的面向對象編程
- Python 模塊
- Python 中的包
- Python 異常
- Python 迭代器和生成器
- Python 內省
- Python Faker 教程
- Python f 字符串教程
- Python bcrypt 教程
- Python 套接字教程
- Python smtplib教程
- OpenPyXL 教程
- Python pathlib教程
- Python YAML 教程
- Python 哈希教程
- Python ConfigParser教程
- Python 日志教程
- Python argparse 教程
- Python SQLite 教程
- Python Cerberus 教程
- Python PostgreSQL 教程
- PyMongo 教程
- PyMySQL 教程
- Peewee 教程
- pyDAL 教程
- pytest 教程
- Bottle 教程
- Python Jinja 教程
- PrettyTable 教程
- BeautifulSoup 教程
- pyquery 教程
- Python for循環
- Python 反轉
- Python Lambda 函數
- Python 集合
- Python 映射
- Python CSV 教程-讀寫 CSV
- Python 正則表達式
- Python SimpleJson 教程
- SymPy 教程
- Pandas 教程
- Matplotlib 教程
- Pillow 教程
- Python FTP 教程
- Python Requests 教程
- Python Arrow 教程
- Python 列表推導式
- Python 魔術方法
- PyQt 中的QPropertyAnimation
- PyQt 中的QNetworkAccessManager
- ZetCode Ruby 教程
- Ruby 教程
- Ruby
- Ruby 語法結構
- Ruby 基礎
- Ruby 變量
- Ruby 中的對象
- Ruby 數據類型
- Ruby 字符串
- Ruby 表達式
- Ruby 控制流
- Ruby 數組
- Ruby 哈希
- Ruby 中的面向對象編程
- Ruby 中的面向對象編程 II
- Ruby 正則表達式
- Ruby 輸入&輸出
- Ruby HTTPClient教程
- Ruby Faraday 教程
- Ruby Net::HTTP教程
- ZetCode Servlet 教程
- 從 Java Servlet 提供純文本
- Java Servlet JSON 教程
- Java Servlet HTTP 標頭
- Java Servlet 復選框教程
- Java servlet 發送圖像教程
- Java Servlet JQuery 列表教程
- Servlet FreeMarker JdbcTemplate 教程-CRUD 操作
- jQuery 自動補全教程
- Java servlet PDF 教程
- servlet 從 WAR 內讀取 CSV 文件
- Java HttpServletMapping
- EasyUI datagrid
- Java Servlet RESTFul 客戶端
- Java Servlet Log4j 教程
- Java Servlet 圖表教程
- Java ServletConfig教程
- Java Servlet 讀取網頁
- 嵌入式 Tomcat
- Java Servlet 分頁
- Java Servlet Weld 教程
- Java Servlet 上傳文件
- Java Servlet 提供 XML
- Java Servlet 教程
- JSTL forEach標簽
- 使用 jsGrid 組件
- ZetCode Spring 教程
- Spring @Bean注解教程
- Spring @Autowired教程
- Spring @GetMapping教程
- Spring @PostMapping教程
- Spring @DeleteMapping教程
- Spring @RequestMapping教程
- Spring @PathVariable教程
- Spring @RequestBody教程
- Spring @RequestHeader教程
- Spring Cookies 教程
- Spring 資源教程
- Spring 重定向教程
- Spring 轉發教程
- Spring ModelAndView教程
- Spring MessageSource教程
- Spring AnnotationConfigApplicationContext
- Spring BeanFactoryPostProcessor教程
- Spring BeanFactory教程
- Spring context:property-placeholder教程
- Spring @PropertySource注解教程
- Spring @ComponentScan教程
- Spring @Configuration教程
- Spring C 命名空間教程
- Spring P 命名空間教程
- Spring bean 引用教程
- Spring @Qualifier注解教程
- Spring ClassPathResource教程
- Spring 原型作用域 bean
- Spring Inject List XML 教程
- Spring 概要文件 XML 教程
- Spring BeanDefinitionBuilder教程
- Spring 單例作用域 bean
- 獨立的 Spring 應用
- 經典 Spring 應用中的JdbcTemplate
- Spring EmbeddedDatabaseBuilder教程
- Spring HikariCP 教程
- Spring Web 應用簡介
- Spring BeanPropertyRowMapper教程
- Spring DefaultServlet教程
- Spring WebSocket 教程
- Spring WebJars 教程
- Spring @MatrixVariable教程
- Spring Jetty 教程
- Spring 自定義 404 錯誤頁面教程
- Spring WebApplicationInitializer教程
- Spring BindingResult教程
- Spring FreeMarker 教程
- Spring Thymeleaf 教程
- Spring ResourceHandlerRegistry教程
- SpringRunner 教程
- Spring MockMvc 教程
- ZetCode Spring Boot 教程
- Spring Boot 發送電子郵件教程
- Spring Boot WebFlux 教程
- Spring Boot ViewControllerRegistry教程
- Spring Boot CommandLineRunner教程
- Spring Boot ApplicationReadyEvent 教程
- Spring Boot CORS 教程
- Spring Boot @Order教程
- Spring Boot @Lazy教程
- Spring Boot Flash 屬性
- Spring Boot CrudRepository 教程
- Spring Boot JpaRepository 教程
- Spring Boot findById 教程
- Spring Boot Data JPA @NamedQuery教程
- Spring Boot Data JPA @Query教程
- Spring Boot Querydsl 教程
- Spring Boot Data JPA 排序教程
- Spring Boot @DataJpaTest教程
- Spring Boot TestEntityManager 教程
- Spring Boot Data JPA 派生的查詢
- Spring Boot Data JPA 查詢示例
- Spring Boot Jersey 教程
- Spring Boot CSV 教程
- SpringBootServletInitializer教程
- 在 Spring Boot 中加載資源
- Spring Boot H2 REST 教程
- Spring Boot RestTemplate
- Spring Boot REST XML 教程
- Spring Boot Moustache 教程
- Spring Boot Thymeleaf 配置
- Spring Boot 自動控制器
- Spring Boot FreeMarker 教程
- Spring Boot Environment
- Spring Boot Swing 集成教程
- 在 Spring Boot 中提供圖像文件
- 在 Spring Boot 中創建 PDF 報告
- Spring Boot 基本注解
- Spring Boot @ResponseBody教程
- Spring Boot @PathVariable教程
- Spring Boot REST Data JPA 教程
- Spring Boot @RequestParam教程
- Spring Boot 列出 bean
- Spring Boot @Bean
- Spring Boot @Qualifier教程
- 在 Spring Boot 中提供靜態內容
- Spring Boot Whitelabel 錯誤
- Spring Boot DataSourceBuilder 教程
- Spring Boot H2 教程
- Spring Boot Web JasperReports 集成
- Spring Boot iText 教程
- Spring Boot cmd JasperReports 集成
- Spring Boot RESTFul 應用
- Spring Boot 第一個 Web 應用
- Spring Boot Groovy CLI
- Spring Boot 上傳文件
- Spring Boot @ExceptionHandler
- Spring Boot @ResponseStatus
- Spring Boot ResponseEntity
- Spring Boot @Controller
- Spring Boot @RestController
- Spring Boot @PostConstruct
- Spring Boot @Component
- Spring Boot @ConfigurationProperties教程
- Spring Boot @Repository
- Spring Boot MongoDB 教程
- Spring Boot MongoDB Reactor 教程
- Spring Boot PostgreSQL 教程
- Spring Boot @ModelAttribute
- Spring Boot 提交表單教程
- Spring Boot Model
- Spring Boot MySQL 教程
- Spring Boot GenericApplicationContext
- SpringApplicationBuilder教程
- Spring Boot Undertow 教程
- Spring Boot 登錄頁面教程
- Spring Boot RouterFunction 教程
- ZetCode Symfony 教程
- Symfony DBAL 教程
- Symfony 表單教程
- Symfony CSRF 教程
- Symfony Vue 教程
- Symfony 簡介
- Symfony 請求教程
- Symfony HttpClient教程
- Symfony Flash 消息
- 在 Symfony 中發送郵件
- Symfony 保留表單值
- Symfony @Route注解教程
- Symfony 創建路由
- Symfony 控制臺命令教程
- Symfony 上傳文件
- Symfony 服務教程
- Symfony 驗證教程
- Symfony 翻譯教程