Visual Basic 6/VBScript 與Visual Basic.NET 的比較(下)

80酷酷网    80kuku.com

  vbscript|visual
新的簡易設定(assignment)語法
Visual Basic.NET 提供新的簡易設定語法,當程式碼撰寫如下時
  MyVal = 10
MyVal += 10
這時 MyVal 的值為 20 ,程式碼等於
  MyVal = MyVal + 10

繼承(Inheritance)
Visual Basic.NET 現今是一個完整的物件導向(Object Orient)語言,也就是完整支援封裝、繼承、多型等等程式撰寫的方式,並提供建構/解構子。所以它增加了以往 Visual Basic 在這一方面所缺乏的功能,如繼承。
Visual Basic.NET 增加的繼承讓你可以其他的 Class 為基礎來建立新的 Class,衍生的(Derived) Class 可以繼承(inherit)和延伸原始 Class 的屬性和方法。雖然衍生的 Class 只能繼承自單一的基礎(base) Class,但它可以實做(implement)無限數目的介面(interface)。衍生的 Class 也可以撰寫新的方法 override 繼承下來的方法,所有 Visual Basic.NET 建立的 Class 預設都是可以被繼承的。
繼承和介面讓你可以實做多型(polymorphism),讓不同的 class 可以重新定義相同名稱的屬性和方法。多型是物件導向(object-orient)程式設計的基礎,因為它讓你可以呼叫相同名稱的方法,而不管在使用的當下是哪一種型態的物件。例如給一個 NormalPayroll 的基礎 class,多型讓程式設計師可以定義多個衍生 Class 不同的 PayEmployee 方法。其他的屬性和方法可以相同的方式使用衍生物件的 PayEmployee 方法,而不管是用到哪一個衍生的物件。
Visual Basic.NET 提供下列的語句來定義和支援繼承

  • Inherits 語句 -- 定義當下 Class 要繼承的 Class(也稱為基礎 class)。通常可以透過屬性視窗(properties window)來設定。
  • NotInheritable 定義子 -- 防止使用者將該 Class 當作基礎 class 來使用
  • MustInherit 定義子 -- 定義該 class 不能用來建立 instance,唯一使用它的方式是繼承它。

衍生的 class 可以新的實做方式 override 一些繼承來的方法。Visual Basic.NET 使用下列的定義子來控制方法和屬性的 overriding
  • Overridable -- 讓屬性和方法在繼承的 Class 可以 override
  • Overrides -- 定義要 override 哪一個基礎的屬性或方法
  • NotOverridable(預設) -- 防止屬性或方法被繼承的 class override
  • MustOverride -- 要求繼承的 class 一定要 override 該屬性或方法

程式碼範例如下 Imports System

Namespace MyNamespace Class Payroll
Overridable Function PayEmployee(ByVal HoursWorked As Single, ByVal PayRate As Single)
PayEmployee = HoursWorked * PayRate
End Function
End Class Class BonusPayroll
Inherits Payroll
Overrides Function PayEmployee(ByVal HoursWorked As Single, ByVal PayRate As Single)
PayEmployee = (HoursWorked * PayRate) * 1.45 ' 45% 紅利
End Function
End Class Module
MyModule Sub Main()
Dim BonusPayrollItem As Bonuspayroll = New Bonuspayroll
Dim PayrollItem As Payroll = New Payroll
Dim PayRate As Single = 14.75
Dim HoursWorked As Single = 40


Console.WriteLine("Normal pay is: " & Pay(PayrollItem, HoursWorked, PayRate))
Console.WriteLine("Pay with bonus is: " & Pay(BonusPayrollItem, HoursWorked, PayRate))


End Sub Function Pay(ByVal PayObject As Payroll, ByVal HoursWorked As Single, ByVal
PayRate As Single) Pay = PayObject.PayEmployee(HoursWorked, PayRate) * 0.75 ' withold tax
End Function
End Module
End Namespace 執行結果如下 在程式碼中你可以看到Class BonusPayroll 繼承自 Payroll,並 Override PayEmployee 函數。所以當 Pay 函數傳入不同的 Class 物件但呼叫相同的方法時,可以有不同的結果。所以以上的程式範例也同時展現了多型的使用方式。

Free Threading
在以往版本的 VB 中,開發者除非藉由 Win 32 API 否則無法開發多 threading 的應用程式,所以只能做同步的動作,也就是程式碼必須要循序地執行。Visual Basic.NET 讓你可以撰寫 multiple task 的應用程式。每一個 Task 可以在一條 thread 內執行,程序(process)可以是 free thread。程式碼範例如下 Imports System.Threading

...

Private iVal, iary(1) As Integer

...

Protected Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim t As New Thread(AddressOf AddVal)
t.Start()
End Sub
Sub AddVal()
SyncLock iary
Dim i As Integer
For i = 1 To 1000000
ival += 1
Next textbox1.text = CStr(ival)
end synclock
End Sub

建構子(Constructor)和解構子(Destructor) 建構子是用來控制 Class 在建立一個新的 Instance 時所需要做的初始化程序。同樣地,解構子是當 Class 的 Instance 結束時(可能是設定變數為 Nothing)所需要做的程序,如釋放系統資源等等。 在原有的 VB 中,可以利用 Class_Initialize() 和 Class_Terminate() 事件程序(Event Procedure)來初始化或在 Instance 結束時執行。


在 Visual Basic.NET 中改以 Sub New() 和 Sub Destruct() 程序來做建構子與解構子的動作。


Sub New() 方法只會在 Class 建立時執行一次,且除了以同一 Class 其他的建構子或是衍生 Class 的建構子的第一行程式碼呼叫之外,不可以在任何其他地方呼叫使用。且 Sub New() 方法之內的程式碼在執行時,沒有任何該 Class 內的成員已經被建立出來。 .NET 執行環境會在清掉物件時自動呼叫它的 Sub Destruct() 方法,這一個副函數也不可以被呼叫使用。


.NET 執行環境在系統決定該物件不需要存在時﹔會自動清掉該物件。與 Class_Terminate 和 Sub New() 不同的是,你無法確切地知道 .NET 執行環境會何時呼叫 Sub Destruct(),只能確定的是對該物件最後的一個參照(reference)被釋放後,系統會自動呼叫 Sub Destruct()。

■ 使用 Sub New() 來建立參數化的建構子 --要建立一個 class 的建構子可以在 class 定義範圍內的任何地方撰寫 Sub New() 副函數。建構子的第一行程式碼必須是呼叫基礎 Class 的建構子或是同一 Class 內其他的建構子,這保證被繼承的物件會在衍生的物件之前初始化完成。甚至是當你在建立你自己的基礎 class 時,也通常會呼叫 MyBase.New 來初始化更基礎的物件,因為所有的 Class 最終都是繼承自 Object Class。


在呼叫完父物件的建構子後,在 Sub New() 副函數內加上初始化該物件所需要的動作。Sub New() 副函數可以接受參數,如下列的程式碼範例。

■ 使用 Sub Destruct() 當解構子 --要建立 class 的解構子,可以在 class 的定義範圍內任何地方加上 Sub Destruct() 副函數。你可以在該副函數內加上釋放物件,關閉檔案等等工作。
程式碼範例如下
Imports System


Namespace MyNamespace


Module MyModule
Class Truck
Private iWheels As Integer
Sub New(iInitialWheels As Integer)
MyBase.New '呼叫基礎 Class 的建構子
iWheels=iInitialWheels
End Sub
Sub Destruct()
'執行一些需要的動作
End Sub
Property Wheels As Integer
Get
Wheels=iWheels
End Get
Set
iWheels = Value
End Set
End Property
End Class


Sub Main()
Dim t as Truck = New Truck(18)
Console.WriteLine("這是一部 {0} 輪大卡車",t.Wheels)
Console.Write("請輸入您想要改裝的輪數: ")
t.Wheels = CInt(Console.ReadLine())
Console.WriteLine("你已經把它改裝成 " & t.Wheels & " 輪大卡車")
End Sub


End Module


End Namespace 執行結果如下

DelegateDelegates 的行為像一個 type-safe,物件導向式函數指標(object-oriented function pointer)。利用 delegate 傳遞用 VB 的 addressof 運算子取得 class 副函數的指標給其他的 VB class 副函數。通常會利用 Delegate 來做事件處理函數,也就是當事件發生時要自動執行的函數。


每一個 delegate class 定義一個建構子,使用時會傳入一個物件方法的指標當作是參數。參數的格式如下
  AddressOf [.]<方法名稱>
在編譯時期, 必須是一個 class 或是一個介面(interface),並且有著一個符合 delegate class 所宣告的方法格式的方法。
這個方法可以是共享的(class)方法或是 instance 方法。 要觸發 delegate class 的 instance 內的方法必須要呼叫內建的 Invoke 方法,整個程式碼範例如下
Imports System
Namespace TestDelegate
Public Delegate Sub EventHandler(ByVal strText As String)


Class EventTake
Sub GetEvent(ByVal strIn As String)
console.WriteLine("Delegate 事件 " & strIn)
End Sub
End Class


Class EventRaise
Sub UseInvoke()
Dim c As New EventTake()
Dim DelSub As EventHandler
delsub = New EventHandler(AddressOf c.getevent)
delsub.Invoke("一些狀況")
End Sub
End Class


Module Module1


Shared Sub Main()
Dim c2 As New EventRaise()
c2.UseInvoke()
End Sub


End Module


End Namespace 執行結果如下

分享到
  • 微信分享
  • 新浪微博
  • QQ好友
  • QQ空间
点击: