第16章 VB.NET物件導向與.NET Framework 16-1 物件導向的基礎 16-2 類別與物件 16-3 類別的繼承 16-4 .NET Framework的基礎 16-5 使用.NET FCL的類別 16-6 習題
16-1 物件導向的基礎 16-1-1 物件的基本觀念 16-1-2 物件導向程式分析 16-1-3 物件導向程式語言
16-1-1 物件的基本觀念 「物件」(Object)是物件導向技術的關鍵,以程式的角度來說,物件是資料與相關程序和函數結合在一起的組合體,如下圖所示: 物件都擁有兩個特性,如下所示: 狀態(State):描述物件的特點,也就是資料的部分。 行為(Behavior):行為就是物件可以作什麼事,這就是程序和函數。
16-1-2 物件導向程式分析-問題 在1970~80年間主要的軟體工程程式分析方法是「由上而下分析法」(Top-down Design),不過這種分析方法有一些問題,如下所示: 由上而下分析法的整個處理過程,只是找出解決問題的程序或函數,也就是各別函數的程式碼,而沒有真正的考量到程式使用的資料本身。 由上而下分析法得到的函數很難被重複使用,因為這些函數都是針對特定問題量身定製,函數需要大幅修改才能使用在其它問題上。
16-1-2 物件導向程式分析-說明 物件導向的程式分析是將原來專注於演算法的程序和函數分解,轉換成了解問題本質的物件,將整個軟體視為一個個定義完善的物件,整個程式是由這些物件所組成,強調物件的重複使用,在建立好下一層的每一個物件後,由下而上組合成整個應用程式的物件,以解決整個問題。
16-1-3 物件導向程式語言 目前所謂的「物件導向程式語言」(Object-oriented Language)支援的三種特性,如下: 封裝(Encapsulation):將資料和處理資料的函數組合起來建立成物件。在VB.NET定義物件是使用「類別」(Class),它屬於一種抽象的資料型別,換句話說,它和結構類似,也是替程式語言定義新的資料型別。 繼承(Inheritance):物件的再利用,當定義好一個類別後,其它類別可以繼承這個類別的資料和方法,新增或取代繼承物件的資料和方法。 多形(Polymorphism):多形屬於物件導向最複雜的特性,類別如果需要處理各種不同的資料型別,此時並不需要針對不同的資料型別建立各別的類別,可以直接繼承基礎類別,繼承此類別建立同名方法處理不同的資料型別,因為方法的名稱相同,只是程式碼不同,所以稱為「同名異式」。
16-2 類別與物件 16-2-1 宣告類別與建立物件 16-2-2 方法的過載 16-2-3 類別的建構子
16-2 類別與物件 VB.NET的類別是物件的原型,或者說是物 件的藍圖,然後我們可以使用這個藍圖建 立物件,它是一種使用者自行定義的資料 型別。
16-2-1 宣告類別與建立物件-說明 VB.NET的類別宣告是物件的原型宣告,這是宣告在Class/End Class之間,類別宣告可以分為兩個部分,如下所示: 成員資料(Data Member):物件的資料部分或稱為「成員變數」(Member Variables),在VB.NET通常是使用宣告成Private的變數配合宣告成Public的Property程序屬性來存取。 成員方法(Method Member):物件處理資料的程式與函數,也就是方法。
16-2-1 宣告類別與建立物件-類別宣告 在VB.NET可以將類別建立成獨立的程式檔案,即在專案中加入類別檔,類別宣告的格式,如下所示: Public Class 類別名稱 成員資料 成員方法 End Class
16-2-1 宣告類別與建立物件-物件屬性的宣告1 VB.NET的屬性是用來存取類別的資料,通常我們會將資料宣告成Private以便隱藏資訊,然後使用物件屬性來存取資料,如下所示: Public Class MyDate Private intDay As Integer Private intMonth As Integer Private intYear As Integer Property Day() As Integer Get Return intDay End Get Set(ByVal Value As Integer) intDay = Value End Set End Property End Class
16-2-1 宣告類別與建立物件-物件屬性的宣告2 在Property程序中擁有Get和Set程序,如下所示: Get程序:取得成員資料值,以此例傳回intDay變數的值。 Set程序:指定成員資料值,程式碼使用指定敘述將屬性值指定成Value參數的值。 如果屬性是唯讀屬性,需要使用ReadOnly修飾子,如下所示: ReadOnly Property Day() As Integer Get Return intDay End Get End Property
16-2-1 宣告類別與建立物件-物件方法的宣告 VB.NET類別的方法是宣告成Public的程序或函數,其程式碼如下所示: Public Class MyDate ………… Public Function GetDate() As String ……….. End Function Public Sub SetDate(ByVal d As Integer, _ ByVal m As Integer, ByVal y As Integer) End Sub End Class
16-2-1 宣告類別與建立物件-建立物件 在VB.NET建立物件是使用New運算子,這個指令依照類別的範本來建立物件,傳回指向此物件的參考(因為物件是參考型別),如下所示: Dim today As MyDate = New MyDate() Dim yesterday As MyDate = New MyDate() 在建立好物件後,就可以存取物件的屬性與方法,其語法如下所示: 物件.屬性 物件.方法
16-2-2 方法的過載 VB.NET的程序與函數允許擁有兩個以上同名的方法,只是傳遞的參數個數或資料型別不同,稱為「過載」(Overloads),在VB.NET宣和程序與函數過載,只需在之前加上Overloads關鍵字,如下所示: Overloads Function Square(ByVal no As Integer) As _ Integer Overloads Function Square(ByVal no As Double) As Double 參數個數不同的過載方法,如下所示: Public Overloads Sub SetDate(ByVal d As Integer,ByVal m _ As Integer,ByVal y As Integer) As Integer)
16-2-3 類別的建構子-說明 VB.NET的基本資料型別在宣告變數時會配置所需的記憶體和指定預設的初值,類別的變數並不會自動建立物件。 如果類別沒有「建構子」(Constructors),在使用運算子New建立物件時,物件預設的建構子只會配置記憶體空間,並不會指定成員變數的初值,即初始物件。
16-2-3 類別的建構子-特點 建構子擁有一些特點,如下所示: VB.NET的建構子是名為New的程序,宣告成Public,例如:類別MyDate的建構程序是New()。 建構子沒有傳回值。 建構子支援過載,可以擁有多個同名的建構子,只是擁有不同的參數型別和個數,如下所示: Public Sub New() Public Sub New(ByVal d As Integer, _ ByVal m As Integer) ByVal m As Integer, ByVal y As Integer)
16-3 類別的繼承 16-3-1 類別繼承的基礎 16-3-2 類別繼承的實例
16-3 類別的繼承 「繼承」(Inheritance)是物件導向程式 設計的進階觀念,繼承是一個類別可以直 接繼承現存類別的部分或全部的成員資料 和方法,並且新增額外的成員資料或方法, 甚至覆寫繼承類別的方法。
16-3-1 類別繼承的基礎-類別關係 如果一個類別是繼承自其它的類別,我們稱這個類別為繼承類別的「子類別」(Subclass)或「延伸類別」(Derived Class),繼承的類別稱為「父類別」(Superclass)或「基礎類別」(Base Class),例如:類別B是繼承自類別A,此時的繼承關係,如下圖所示:
16-3-1 類別繼承的基礎-兄弟類別 如果有多個子類別繼承同一個父類別,每一個子 類別稱為「兄弟類別」(Sibling Classes),如 下圖所示:
16-3-2 類別繼承的實例-父類別 一個範例程式來說明類別繼承的觀念。父類別TextLine定義一列文字字串,如下所示: Public Class TextLine Private str As String ' 建構子 Public Sub New() str = "" End Sub ………… End Class
16-3-2 類別繼承的實例-類別的繼承語法 在VB.NET可以建立新的類別檔(也可以在同一個檔案)來繼承已經存在的類別,其宣告的語法,如下所示: Public Class 子類別名稱 Inherits父類別名稱 …… ' 額外的成員資料和方法 End Class 上述語法使用Inherits關鍵子擴充父類別的原型宣告。
16-3-2 類別繼承的實例-子類別的範例 MyLine子類別的宣告,如下所示: Public Class MyLine Inherits TextLine ' 建構子 Public Sub New() MyBase.New() End Sub ………… End Class 上述程式碼的MyLine子類別是繼承自TextLine父類別,子類別可以使用MyBase來呼叫父類別的建構子、方法和屬性,然後可以在子類別新增屬性、方法或覆寫父類別的方法。
16-3-2 類別繼承的實例-存取限制 雖然子類別可以繼承父類別所有的成員資料和方法,但是在存取時仍然有一些限制,如下所示: 子類別不能存取父類別宣告成Private的成員資料和方法。 父類別的建構子不屬於類別的成員,所以子類別並不能繼承父類別的建構子,只能使用MyBase呼叫父類別的建構子。
16-3-2 類別繼承的實例-覆寫父類別的方法(父) VB.NET可以在父類別宣告Overridable關鍵字,表示此方法可以覆寫,如下所示: Public Class TextLine Private str As String ' 建構子 ………… ' 可覆寫的方法 Public Overridable Sub ShowText() Console.WriteLine(LCase(str)) End Sub End Class
16-3-2 類別繼承的實例-覆寫父類別的方法(子) 繼承的子類別就可以使用Overrides關鍵字來覆寫,如下所示: Public Class MyLine Inherits TextLine ' 建構子 ………… ' 覆寫方法 Public Overrides Sub ShowText() Console.WriteLine(MyBase.Line) End Sub End Class
16-4 .NET Framework的基礎 16-4-1 Common Language Runtime 16-4-2 .NET FCL
16-4 .NET Framework的基礎 VB.NET是支援.NET Framework的程式語言,.NET Framework是微軟下一個世代的程式開發平台,由「CLR」(Common Language Rumtime)和.NET Framework類別函式庫」(.NET Framework Class Library,簡稱.NET FCL)所組成。
16-4-1 Common Language Runtime-1 當.NET Framework支援的程式語言,例如:VB.NET、C#和JScript.NET等編寫的程式碼,使用.NET的編譯程式進行編譯,編譯檔案並不是編譯成CPU了解的機器語言,而是一種中間程式語言稱為「MSIL」(Microsoft Intermediate Language)。
16-4-1 Common Language Runtime-2 當需要執行程式時,CLR使用其「JIT」(Just In Time)編譯程式將MSIL轉換成機器語言來執行,如下圖所示:
16-4-2 .NET FCL-說明 .NET FCL是一個龐大的類別函式庫,只需支援.NET Framework的程式語言都可以使用類別函式庫的類別和方法。這是一個稱為Namespace名稱空間的階層類別架構,每一個名稱空間可以擁有無限數目的類別,如下圖所示:
16-4-2 .NET FCL-VB.NET參考 VB.NET建立的Windows應用程式和主控台應用 程式專案預設會匯入相關的名稱空間(即專案的 【參考】項目)的DLL檔案,如下圖所示:
16-4-2 .NET FCL-預設參考
16-5 使用.NET FCL的類別 16-5-1 ArrayList物件 16-5-2 Hashtable物件 16-5-3 StringBuilder物件
16-5 使用.NET FCL的類別 VB.NET函數都可以改為使用.NET FCL類別物件的方法來取代。 VB.NET函數並沒有提供的.NET FCL類別,有集合物件和StringBuilder物件,詳細的.NET FCL類別可以參閱「Microsoft .NET Framework SDK的說明文件」。 「集合物件」(Collections)是用來處理一些不定元素數的資料(類似動態陣列),這種物件讓程式設計者不用考慮記憶體配置的問題,只需使用其方法就可以新增、刪除和插入集合物件中的元素。
16-5-1 ArrayList物件-建立 ArrayList物件儲存元素的方式類似陣列,元素是以索引方式依序的儲存,只需將元素新增或插入ArrayList物件,而不用事先宣告物件的大小,建立物件的方式,如下所示: Dim names As ArrayList = New ArrayList()
16-5-1 ArrayList物件-屬性
16-5-1 ArrayList物件-方法
16-5-1 ArrayList物件-取得元素 在新增ArrayList物件的元素後,.NET Framework的集合物件可以使用For Each迴圈取得物件的所有元素,如下所示: For Each str In names Console.WriteLine("[" & str & "]") Next
16-5-2 Hashtable物件-建立 Hashtable物件的元素需要指定一個Key值來排列,新增元素自動是以Key值的英文字母順序進行排序,所以只有Add方法,而沒有Insert方法,同樣使用New運算子建立,如下所示: Dim users As Hashtable = New Hashtable() 在建立好Hashtable物件users後,就可以使用Add方法新增元素,如下所示: users.Add("hueyan", "陳會安") users.Add("jane", "江小魚") users.Add("joe", "陳小安") users.Add("tom", "張無忌")
16-5-2 Hashtable物件-屬性
16-5-2 Hashtable物件-方法
16-5-2 Hashtable物件-取出元素 Hashtable物件的元素儲存Key和Value兩個值,所以在For Each迴圈需要使用Keys屬性取得Key值的物件集合,以便取出物件元素,如下所示: For Each str In users.Keys Console.WriteLine("[" & str & ":" & _ users(str) & "]") Next 上述程式碼取得每一個元素的Key值,使用users(str)取得每一個元素的Value值。
16-5-3 StringBuilder物件-說明 StringBuilder類別類似字串String物件,屬於System.Text名稱空間,因為VB.NET專案預設並沒有匯入此名稱空間,所以在程式開頭需要自行匯入此名稱空間,如下所示: Imports System.Text StringBuilder是一種允許更動字串內容的物件,而不用重新建立字串,使用Append、Insert、Remove和Replace方法處理字串內容。
16-5-3 StringBuilder物件-建立 Dim builder as StringBuilder = _ New StringBuilder("VB.NET程式設計", 10) 上述程式碼使用New運算子建立StringBuilder物件builder,第1個參數是字串內容,第2個參數是StringBuilder物件的容量。
16-5-3 StringBuilder物件-屬性
16-5-3 StringBuilder物件-方法
16-5-3 StringBuilder物件-方法