1 / 154

第五章 物件導向

第五章 物件導向. ASP.NET 程式不論是採用 VB 或 C# 語法來開發,都脫離不了物件與類別,因為代表網頁的本身就是一個類別、而每一種控制項的定義也都是一個類別。 雖然本書大部分採用單一檔案模式開發,不會看到繼承使用的 Inherits 關鍵字,並且我們也不自行開發類別,但本書仍將利用 .NET Framework 提供的眾多類別來開發 ASP.NET 程式,故在本章中,我們將介紹 VB 的物件導向語法,並且介紹 Web Form 網頁最基本的 Page 類別。. 大綱. ( 本章為電子檔 PDF, 可直接以 PDF 教學 )

gili
Download Presentation

第五章 物件導向

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第五章 物件導向 ASP.NET程式不論是採用VB或C#語法來開發,都脫離不了物件與類別,因為代表網頁的本身就是一個類別、而每一種控制項的定義也都是一個類別。 雖然本書大部分採用單一檔案模式開發,不會看到繼承使用的Inherits關鍵字,並且我們也不自行開發類別,但本書仍將利用.NET Framework提供的眾多類別來開發ASP.NET程式,故在本章中,我們將介紹VB的物件導向語法,並且介紹Web Form網頁最基本的Page類別。

  2. 大綱 • (本章為電子檔PDF,可直接以PDF教學) • 5.1 物件導向程式設計(若時程允許,建議教學) • 5.1.1 類別與物件 • 5.1.2 繼承與實作 • 5.2 命名空間(若時程允許,建議教學) • 5.2.1 .NET Framework的類別 • 5.2.2 Microsoft.VisualBasic命名空間 • 5.2.3 引入命名空間 • 5.3 傳統VB常用函式(請學生參考書附光碟檔自學)

  3. 大綱 • 5.4 System的常用類別(請學生參考書附光碟檔自學) • 5.4.1 System.Object類別 • 5.4.2 System.String類別 • 5.4.3 System.Math類別 • 5.4.4 System.DateTime結構 • 5.4.5 System.Random類別 • 5.4.6 System.Array類別 • 5.4.7 線上說明 • 5.5 網頁生命週期與Page物件(若時程允許,建議教學) • 5.5.1 ASP.NET生命週期 • 5.5.2 Page物件 • 5.5.3 Response屬性 • 5.5.4 Request屬性 • 5.6 共用事件程序(請學生參考書附光碟檔自學) • 5.7 本章回顧

  4. 第五章 物件導向 • 本章將介紹Web Form網頁最基本的Page類別,以及具有各種用途的特定類別(例如可用來進行數學計算、字串轉換) • 由於篇幅有限,我們無法提供所有類別與方法的使用範例,僅將方法列於表格說明,您若需要使用該方法,可以查閱msdn線上說明。 • 為了讓讀者更容易了解msdn線上說明,因此,我們必須先介紹VB的物件導向術語,並適時地介紹ASP.NET可能使用到的類別。

  5. 5.1 物件導向程式設計 • 物件導向包含三大特性(封裝、繼承、多型),在本節中,我們將說明VB.NET與ASP.NET的物件導向觀念,有了這些觀念,當您在閱讀線上說明文件時,就能理解其中相關術語的意義。 • 5.1.1 類別與物件 • VB.NET是一個物件導向程式語言,程式是由各式各樣的類別所構成。而物件則是類別的實體。 • 舉例來說,Button按鈕是一個類別(Class),而視窗或網頁上的每一個按鈕都是一個物件(Object)。

  6. 5.1.1 類別與物件 • 定義類別與宣告物件 • 若不使用系統提供的類別,使用者可以自行定義類別,簡略的語法如下: [修飾字] Class 類別名稱 [繼承類別] '若需繼承自其他類別時才需使用 [實作介面] '若需實作某些介面時才需使用 定義類別的屬性 定義類別的欄位 定義類別的建構函式 定義類別的方法 定義類別的其他資料,例如常數、事件、運算子 End Class

  7. 5.1.1 類別與物件 • 封裝 • 封裝性是物件導向的特性之一,它使用於定義類別成員時,例如定義類別的「欄位」和「方法」。 • 封裝是代表該成員是否可被外部(其他類別)使用,常用的封裝層級為Public、Private、Protected等,分別代表公開、私用、可繼承使用。 • 本書並不需要自行宣告類別,有興趣的讀者可自行參閱VB專書或線上說明。在本章中,我們會提示許多相關名詞,以便讀者在閱讀線上說明時不致產生困惑。 • 宣告物件及產生物件實體 • 當類別定義完成後(不論是自行定義或使用.NET Framework提供的現成類別),我們就可以將類別當作一種資料型別來宣告變數。 • 此型別是一種參考型別(Reference Type),也就是變數存放的將是參考。而我們將這種變數稱之為物件變數。 • 當宣告物件變數之後,我們可以利用New關鍵字產生物件實體(instance),物件實體是類別的一個複本,擁有類別的所有成員。

  8. 5.1.1 類別與物件 • 宣告物件與產生物件實體(兩者可合併)的語法如下: • 【範例】 Dim 物件變數1 As 類別名稱 '宣告物件變數 物件變數1 = New 類別名稱(傳入建構函式的引數) '產生物件實體 Dim 物件變數2 As New 類別名稱(傳入建構函式的引數) '宣告物件變數並產生實體 Class Rect Public Length As Integer '宣告Length欄位為公用 Public Width As Integer '宣告Width欄位為公用 Private Area As Integer '宣告Area欄位為私用 Public Sub CalArea() '宣告公用CalArea方法 Area = Length * Width End Sub Public Function GetArea() As Integer '宣告公用GetArea方法 Return Area End Function End Class

  9. 5.1.1 類別與物件 Class 其他類別名稱 Sub 某個方法名稱 '例如Button_OnClick方法 Dim var As Integer Dim objA As New Rect() '宣告物件變數objA並產生實體,可改寫如下兩行 'Dim objA As Rect '宣告物件變數objA 'objA = New Rect() '產生物件實體 objA.Length = 10 '設定objA物件的Length 欄位為10 objA.Width = 5 '設定objA物件的Width 欄位為5 objA.CalArea() '執行objA物件的CalArea方法 var = objA.GetArea() '執行objA物件的GetArea方法 End Sub End Class • 【範例說明】 • (1) 前半部的Class Rect ~~ End Class為自行定義的Rect類別(它擁有3個欄位與兩個方法)。後半部我們在另一個類別的某個方法中使用了自行定義的Rect類別。

  10. 5.1.1 類別與物件 • (2)Dim objA As New Rect(),代表objA為物件變數,它會參考到Rect類別的物件實體。 • 您可以將宣告與產生物件實體改寫為後面兩行。 • (3)objA.Length= 10與objA.Width = 5都是設定物件的欄位值。 • 但我們無法設定Area欄位值,因為它被宣告為Private私用等級,而我們目前是在另一個類別中撰寫程式,故無法存取Area欄位值。 • (4)請注意,不論是哪一種等級的欄位,都可以在類別內的方法中使用,故Area欄位可以在GetArea()與CalArea()中使用。 • (5) 想要設定Area欄位值,可以透過CalArea()來達成,想要取得Area欄位值,可以透過GetArea()來達成,因為這兩個方法都被設定為Public公用等級,故其他類別的程式也可以要求執行它。

  11. 5.1.1 類別與物件 • 上述程式執行後,var的值應該是50,因為它是GetArea()的回傳值。但請注意,只有objA的Length為10、Width為5、Area為50,若宣告其他物件並產生實體(例如objB),則其內的欄位值並不會相同,因為物件之間是獨立的。

  12. 5.1.1 類別與物件 • 欄位(Field)、屬性(Property)和方法(Method) • 請回顧1.5節,我們對於物件導向設計的介紹,當時我們說明了在物件導向設計中,類別包含了屬性與方法,而類別的物件實體也同樣擁有這些屬性與方法。 • 對於VB而言,方法與1.5節介紹的方法是完全相同的,方法是在類別內宣告的Sub或Function程序,屬於該類別與其生成之物件實體專有,並且依照封裝等級決定是否可被其他類別呼叫。 • 除了共用方法之外,方法應該由該類別的實體物件來執行,其功能代表的是物件可採取的行動。 • 例如上述範例中,Rect類別的CalArea()與GetArea()都是Rect類別的方法。 • 而我們是透過實體物件objA來執行它們。 • 但對於VB而言,1.5節所說明的屬性,在VB中稱之為欄位,它可以視為類別或物件的項目,同樣地,它也有封裝等級,並可由封裝等級決定是否可被其他類別存取其值。

  13. 5.1.1 類別與物件 • 然而VB的屬性與1.5節所介紹的屬性有一點點的不同,VB的屬性是介於欄位與方法的綜合體。 • 對於VB而言,屬性仍是一種程序,但其主要目的是存取欄位值。 • VB的屬性藉由Set與Get程序來存取欄位值,那麼存取哪一個欄位值呢? • 在VB2008之前,使用者應該設定一個以上的欄位值以供Set與Get程序存取,並且可以在Set與Get程序內動一些手腳,使得屬性值的設定可以有更多的限制。 • 例如,如果我們將某一個身高設定為人物類別的欄位,則我們只能透過=運算子,指定一個數值給該欄位,並且無法設定其為只能讀不能寫或只能寫不能讀。 • 但如果我們將其宣告為身高屬性而非身高欄位,則我們可以透過Set與Get設定其讀寫特性(例如唯讀或唯寫) • 並且在Set程序中,加入條件判斷,就可以使得當要設定身高屬性時,將其對照的欄位值規範在150~200之間。

  14. 5.1.1 類別與物件 • 在VB2010之後,屬性更像是欄位了,或可視為增強版的欄位,因為VB2010提供了「自動實作屬性」的功能 • 也就是當您將一個類別的項目宣告為屬性時,不再需要提供其他欄位或Set與Get程序,就可以透過=運算子,指定一個數值給該屬性。 • 這是因為編譯器會自動幫這個屬性實作出Set與Get程序,並且宣告一個「_屬性名稱」的欄位,作為實際存放資料的所在。如下範例:

  15. 5.1.1 類別與物件 • 編譯器處理上述新版VB程式碼時,會產生如下的同等效力之程式碼

  16. 5.1.1 類別與物件 • 當然,如果您想在VB2010版使用舊的語法,並且提供了Get/Set程序,則不一定要使用「_屬性名稱」欄位作為其存放資料處。 • 但請注意,若您使用的是「自動實作屬性」功能,則不可以再一次自行定義一個「_屬性名稱」欄位,否則編譯時會出現錯誤。 • 由於將項目宣告為屬性,比將項目宣告為欄位更可以有效管控,因此,VB的控制項之資料項(例如Button的Text),都是宣告為屬性,並且可以在屬性窗格中進行初始的靜態設定。 • 由於VB2010已經提供了「自動實作屬性」功能 • 因此建議,若資料項目是不想公開的,通常會宣告為欄位,並採用Private封裝等級宣告; • 而若是需要對外公開的,則可宣告為屬性,因為Property程序的封裝等級是Public。

  17. 5.1.1 類別與物件 • 字串類別 • 事實上,為了達到跨語言的目的,.Net Framework定義了許多基本資料型別(如表4-1的CLR資料型別),用以對照VB、C#、J#等多種語言所提供的資料型別。 • 例如System.String、System.Int32分別都是一個類別或結構,可以對應VB的String字串型別與Integer整數型別。 • 因此,VB的String字串在編譯時,會被視為一個類別,而VB允許我們省略New關鍵字來產生實體而能夠直接設定它 • 事實上,String類別的字串是一個內容固定而無法改變的字串,當您試圖改變字串內容時,只不過是產生一個新的字串物件實體,並將字串變數參考到新的字串物件實體而已,而原本的字串將在一段時間後被系統自動回收。 【結構(Structure)】 結構是VB提供的另一種定義參考型別的方式,與類別幾乎相同(也具有欄位與方法),可以將內部定義的項目封裝起來。但結構無法使用繼承,故只能使用於不需要擴充時使用。

  18. 5.1.1 類別與物件 • Net Framework之所以將String類別的字串設定為不可變,主要原因是為了在多執行緒環境時避免造成同步問題。 • 下列範例將使用較正式的宣告物件與產生實體的語法來使用物件。 • String類別擁有一個Insert(n,s)方法,實際上它是一個Function程序。當String物件執行它之後,可以在String物件的第n個位置插入一個子字串s,並且回傳其結果,如下範例。 Dim s1 As New String("abcxyz") '執行後s1內容為 "abcxyz" Dim s2 As New String("") '執行後s2內容為 "" 空字串 s2=s1.Insert(3,"ttt") '執行後s2內容為 "abctttxyz"

  19. 5.1.1 類別與物件 • 共用方法(Shared Method) • 上述範例在執行Insert方法時,必須透過String的物件實體s1來執行。有時為了方便方法被使用,因此,VB允許我們定義共用方法(Shared Method), • 而共用方法並不需要產生物件實體,只需要使用「類別名稱.方法名稱()」來執行即可。 • 例如Strings字串類別(不是String類別)有一個LCase(s)方法,可以將s字串的內容全部轉換為小寫後回傳,如下範例。 Dim s3 As New String("ABC") '執行後s3內容為 "ABC" Dim s4 As New String("") '執行後s4內容為 ""空字串 s4 = Strings.LCase(s3) '執行Strings的共用方法LCase後s4內容為 "abc" 【共用方法與靜態方法】 VB的共用方法在其他語言(例如Java)中,一般稱之為靜態方法(static method)。

  20. 5.1.1 類別與物件 • 共用欄位(Shared Filed) • 同理,除了可定義共用方法外,我們也可以在類別內定義共用欄位,如此一來,所有由該類別產生的物件將共用此欄位。 • 並且即使物件消失了,該欄位值也不會消失,因為它必須保留,使得之後產生的物件能夠繼續共用。 • 而定義共用欄位與方法都是使用Shared關鍵字來修飾。 【模組】 類別 (Class) 和模組都是將內部定義的項目封裝起來的參考型別,但類別可實體化 (Instantiated) 為物件實體,而標準模組不行。因為標準模組資料只有一個共用複本,故在模組中所宣告的方法是隱含共用的方法,不必使用Shared關鍵字來宣告。並且類別可以實作介面但標準模組則不行。

  21. 5.1.1 類別與物件 • 建構函式(Constructor) • 這是當類別產生實體物件時會馬上自動執行的函式,通常用以初始化物件的內容,而其名稱為Sub New程序。(不會是Function,因為它不能回傳任何值) • 事件驅動與事件程序(event-handling method) • 事件驅動是視窗程式的新觀念。事件是由物件傳送用以表示發生某個動作的訊息。而動作可能是由使用者操作 (例如按一下) 所造成,也可能是由程式邏輯來觸發 (Trigger)。 • 引發事件的物件稱為事件來源者(Event Source),捕捉事件並且回應它的物件稱為事件接收者(event receiver),所謂「回應」也就是執行某個特定的程序。

  22. 5.1.1 類別與物件 • 程式中必須提供事件處理程序(event-handling method)來回應事件,並且必須將事件處理程序向事件來源者註冊。如此才能使事件來源者與事件接收者產生關聯,這個動作稱之為事件連接(event wiring)。 • VWD與VB IDE都提供了簡化或隱藏事件連接詳細資料的RAD工具。 • 而在本書中,我們使用的事件來源者為Web Form本身或各種控制項,故只需要在屬性窗格中透過選取事件處理程序的方式就能夠完成事件連接,完全不需要學習其詳細機制,只需要了解事件驅動的意義即可。 • 舉例來說,在網頁中若按下按鈕Button1,則按鈕Button1(事件來源者)會產生一個Click事件,而由於IDE已經幫我們完成了事件連接,因此在接收到按鈕Button1的Click事件後會自動執行Button1_Click()事件程序。

  23. 5.1.1 類別與物件 • 多載(Overloading) • 有些時候我們會希望建立一些名稱相同但參數數量或型別不同的多個方法,此時,您可以透過多載(Overloading)機制來達成。 • 例如想要建立一個計算面積的程式,您可以宣告Area(Integer,Integer)與Area(Double,Double)兩個同名的方法,但宣告方法時,必須在Sub或Function前方使用Overloads關鍵字來修飾。 • 除了方法之外,建構函式與類別屬性也可以使用多載機制。 【運算子(Operator)】 當您查閱線上說明時,有時候會在類別內見到運算子(Operator),例如String類別中,有一個Equality運算子,這也是多載化的一種應用,運算子多載化使得運算子可以進行更多型別的運算,例如String字串「=」運算子,可以用來判斷兩個指定的String物件是否具有相同的值。

  24. 5.1.2 繼承與實作 • 繼承也是物件導向的特性之一,它使得原有的類別得以擴充為更多功能的類別。 • 例如我們有一個滑鼠類別,此時若希望開發一個滾輪滑鼠類別,只需要繼承滑鼠類別,然後加上一個滾輪欄位,以及一個滾輪滑動方法即可。 • ASP.NET的網頁繼承 • 在VB中,繼承使用的關鍵字是Inherits,被繼承者稱之為基底類別,繼承者稱之為衍生類別。 • 我們所開發的網頁,在ASP.NET中稱之為Web Form,它事實上是一個Page類別的衍生類別。 • 如果您使用的是程式碼後置模式開發ASP.NET的Web Form網頁,並且在網頁上配置一個Button1按鈕,然後按兩下產生其Click事件的處理程序,則可以在「Default.aspx.vb」檔案中看到下列程式碼:

  25. 5.1.2 繼承與實作 Partial Class _Default '類別名稱為_Default Inherits System.Web.UI.Page '繼承自System.Web.UI.Page Protected Sub Button1_Click(sender As Object, e As System.EventArgs) Handles Button1.Click '事件程序撰寫處 End Sub End Class • 【說明】 • (1)您會看到一個類別宣告,名稱為「_Default」,而第二行則會看到這個類別衍生自(繼承了)System.Web.UI.Page類別。它包含一個事件程序(Button1_Click),事件程序後方的「Handles Button1.Click」則代表它要處理Button1的Click事件。

  26. 5.1.2 繼承與實作 • (2)至於「_Default」類別前方的Partial 關鍵字,則代表此處的類別定義僅限於類別的一部分, • 換句話說,類別的定義並不完全包含在單一檔案中。因此,當網頁執行時,編譯器會讀取 .aspx 網頁以及在『@ Page 指示詞中CodeFile參考的檔案』,並將其組成為單一類別然後進行編譯。而這個組合起來完整的類別就是網頁本身。

  27. 5.1.2 繼承與實作 • (3)類別的另一部分被記載在.aspx檔案中,但若您觀察該檔案並不會看到相關的資料,事實上,每一個控制項都代表著該類別的一個成員。 • 例如<asp:Button ID="Button1" runat="server" Text="Button"></asp:Button>控制項,會使得編譯器產生下列的部分類別中的Button1欄位。 • 由此可知,控制項將會成為網頁類別中的欄位,事實上,我們在範例4-13的第7行所定義的num,也是網頁類別的一個欄位,因為它定義於所有程序之外。 • (4)整體的網頁編譯過程如圖5-1: Partial Class _Default Inherits System.Web.UI.Page Protected Button1 As Button '成員(欄位) End Class

  28. 圖5-1 程式碼後置的網頁編譯過程

  29. 5.1.2 繼承與實作 • 至於如果您使用的是單一檔案模式開發ASP.NET網頁,則由於標籤、控制項及事件處理程序的程式碼都已放置在單一.aspx檔中。故在編譯網頁時,編譯器會產生及編譯新類別,該類別衍生自基底 Page 類別(未設定Inherits屬性時) • 類別名稱將會是「ASP<Page>_aspx」或「<Page>_aspx」 • 其中<Page>為檔案的主檔名 • 一般我們將代表網頁的類別稱為<Page>類別 • 整體的網頁編譯過程如圖5-2:

  30. 圖5-2 單一檔案的網頁編譯過程

  31. 5.1.2 繼承與實作 • 值得注意的是,網頁的生命週期代表著<Page>物件的生成與消滅,<Page>物件是<Page>類別的一個實體 • 當一個網頁的要求產生時,首先ASP.NET會判斷是否需要剖析和編譯網頁 (因此開始網頁的生命週期),或者使用網頁的快取版本。接著網頁會經過一連串的事件 (其中包含PreInit、Load、PreRender等等),最後產生XHTML回傳給客戶端 • 回傳給客戶端之後,還會執行Unload事件程序,然後就會被捨棄(discarded)。 • 網頁被捨棄,代表<Page>物件已經消滅。故當您按下【按鈕】而將表單資料送往同一個網頁時(送往網頁就是代表一個網頁的要求產生),代表著另一個新的網頁生命週期即將展開。 • 而兩次的網頁要求執行的是不同的<Page>物件 • 所以在範例4-13中,num雖然是<Page>類別的欄位,但由於並未設定為共用欄位,故無法保存資料到下一次網頁要求執行時。

  32. 5.1.2 繼承與實作 • 關於使用最大容器保存資料,ASP.NET的Web Form與VB的WindowsForm之效果有些差異,因為VB視窗的Form1類別(繼承自System.Windows.Forms.Form)所產生的<Form>物件,從程式開始到結束的過程中都不會被消滅(除非您開發的是多Form程式),故其內的欄位值可以一直保存,但ASP.NET卻不行,因為ASP.NET的網頁物件是不斷在重複「生成、經歷事件、消滅」的過程。 • 要讓ASP.NET的網頁具有記憶資料的功能,可以將資料宣告為<Page>類別的共用欄位,如此,不論是哪個新的網頁物件實體都可以與其共用,故而達到資料記憶的能力 • (不過這並不是一個好辦法,較佳的作法請見第10章)。

  33. 5.1.2 繼承與實作 • 【範例5-1】 • 改寫範例4-13,使用共用欄位解決資料記憶問題。 • 範例5-1: • 網站目錄 ASPNET\ch05\ch05_01\(檔案ch05_01.aspx) • Step1:網頁介面設計【略,請自行參閱檔案】: • 當中包含一個Button按鈕控制項,名稱為Button1及一個Label標籤控制項,名稱為Label1。 • Step2:撰寫<script>內的程式碼如下:

  34. 範例說明: • (1)第7行:整個程式與範例4-13完全相同,只有在第7行,我們將num欄位改為私用且為共用欄位(使用Shared的效果)。 • (2)請您按下【在瀏覽器中檢視】鈕來執行,執行後每按一次【執行】鈕,num的值都會累加7。

  35. 5.1.2 繼承與實作 • (3) 請重新按下瀏覽器捷徑,開啟另一個瀏覽器(非開啟瀏覽分頁或新索引標籤),並將前一個執行ch05_01.aspx的瀏覽器之網址(例如http://localhost:4890/ch05_01/ch05_01.aspx)複製到新開啟的瀏覽器網址列中,按下【Enter】鍵,此時會讀取同一個網頁,並且您在新瀏覽器中按下【執行】鈕,也會進行num的累加。 • 請切換兩個瀏覽器,並多按幾次【執行】鈕,就可以發現此一現象。 • (4)為何未發生上述的現象呢? • 事實上,不論您是按下哪一個瀏覽器中的【執行】鈕,都代表著一個網頁要求的產生,也就是一個新的網頁生命週期的開始,但當您看到網頁在瀏覽器中顯示的結果時,該網頁生命週期已經結束。 • 所以如果一個網頁的生命週期是由一個<Page>物件來執行,則每按一下【執行】鈕,代表產生一個新的<Page>物件,並且該物件執行完畢後就消失了。 • 而雖然這些<Page>物件是不同的物件,但仍可共用<Page>類別的num共用欄位。所以還是能夠達到記憶的功能(但也會因此造成兩個瀏覽器間相互的影響,我們將在範例6-2、6-3解決這個問題,之後也會改以ViewState等其他機制,達到資料跨網頁共用的目的)。

  36. 5.1.2 繼承與實作 • Step3:執行程式。

  37. 5.1.2 繼承與實作 • 多型與覆寫 • 多型(Polymorphism)也是物件導向的特色之一,代表能夠在執行階段,執行不同功能但名稱完全相同的方法。實現多型的方式之一可透過覆寫方法來完成。 • 舉例來說,我們有一個矩形類別(包含兩個長、寬欄位及一個計算周長方法),而今天想要開發一個正方形類別,則同樣可以繼承自矩形類別,並且不需要增加任何新的欄位與方法。 • 而雖然我們不增加新的方法,但可能舊的(繼承而來的)計算周長方法之程式執行速度較慢(甚至可能已經不敷使用),此時我們可以在衍生類別中,覆寫原本的方法。 • 舉例來說,我們可以在衍生的正方形類別中覆寫原本的計算周長方法。例如原本為(長+寬)*2,而覆寫時,則改為(長*4),以便不使用加法。

  38. 5.1.2 繼承與實作 • 覆寫並不代表原本基底類別的計算周長方法消失了,而是編譯器能夠將其正確處理,使得正方形物件在執行計算周長方法時,能夠執行到覆寫後的計算周長方法。 • 在VB中,要使用覆寫功能來覆寫某一個方法時,使用的關鍵字是Overridable。

  39. 5.1.2 繼承與實作 • 多型與介面 • 介面和類別很相似,但介面僅定義了欄位與方法,並不提供方法的細節程式碼(只定義了方法的名稱)。因此,介面無法產生物件(否則物件執行方法時,不知道要執行什麼程式碼)。 • 要讓介面產生作用,仍必須以某個類別實作該介面,在VB實作介面時,採用的是Implements關鍵字。 • 實作介面和繼承類別很相似,不過實作介面時,必須將所有已定義的方法重新撰寫一份細節程式碼。(而繼承類別時,除非有覆寫之必要,否則可以直接繼承方法來使用。) • 換句話說,我們也可以將實作時撰寫的程式碼看作是覆寫,因此介面也是多型的一種方式,只不過在VB中,實作介面定義的方法時,不是使用Overridable關鍵字。

  40. 5.1.2 繼承與實作 • 【註】以上介紹的類別、物件、繼承等相關物件導向語法,大多數在本書中並不會使用。之所以在此說明,是基於下列理由: • 1. 讓讀者了解,ASP.NET網頁本身將被視為一個<Page>類別來編譯。而該類別繼承自System.Web.UI.Page類別。 • 2.讓讀者了解,即使您在撰寫VB時將String視為一種資料型別,但在編譯為中間檔時,仍會對應到.NET Framework的String類別,故我們可以在程式中直接使用字串物件的方法。 • 3. 讓讀者了解,Label控制項是一個類別。而我們產生的Label1控制項事實上是<Page>類別的一個欄位。故可以在<Page>類別中橫跨多個事件程序自由使用,因為所有的事件程序都是<Page>類別的方法。 • 4. 讓讀者了解,如果您有一些變數想要橫跨多個程序來使用,可以將之宣告在程序之外,此時該變數就會變成是網頁類別的一個欄位(因為整個網頁是被包含在一個<Page>類別內)。

  41. 5.1.2 繼承與實作 • 5. 若您不滿意某個控制項的某個方法,可以透過繼承,然後覆寫該方法來達到修改控制項的目的(因為每個控制項都是一個類別)。 • 6.後面介紹常用類別與方法時,並不會完全列出語法細節,若讀者在查閱線上說明時,遇到相關術語,能夠由本節之說明進行理解。如下: • 您可能會查到某個類別的方法,名稱相同,但參數型別不同,這就是因為使用多載功能的緣故。 • 您可能在查閱某個控制項的欄位時,會發現是屬性,但實際使用上,您可以將屬性當作欄位來使用,但屬性可能被宣告為唯讀或唯寫。 • 有些方法不必產生物件就可以使用,這是因為它被宣告為共用方法。

  42. 5.2 命名空間 • 雖然在上一節中,我們介紹了如何撰寫類別,但本書的重點仍然是使用系統提供的現成類別來開發程式。 • 而現成的類別非常多,尤其是.NET Framework還可以跨語言開發,因此,類別需要被管理,.NET Framework將管理類別的工作交由命名空間來負責。 • 許多程式語言都面臨類別管理的問題,例如Java利用目錄與檔案的唯一性來作為根據,意即在檔案系統中,任何一個檔案的「完整路徑+檔名」不會重複,完整路徑代表類別庫,而檔名代表類別,並且將目錄階層相隔之符號「\」改為「.」,就可以避免類別名稱的重複。 • 而.NET Framework則是採用命名空間(namespace)來區隔,命名空間也是以階層方式進行區隔,並且階層符號為「.」,最後一個「.」右方為類別名稱,而左方則為該類別的命名空間,在此命名空間中,保證不會有相同的類別。

  43. 5.2 命名空間 • 舉例來說,我們常用的Button按鈕類別,在屬性窗格中您會發現其完整的名稱為System.Web.UI.WebControls.Button • 最右方的Button為類別名稱 • 左方的System.Web.UI.WebControls為命名空間的名稱 • 並且在System.Web.UI.WebControls命名空間中,只會有一個Button類別。 • 微軟建議,若公司或個人想要開發類別庫,應該採用「公司名稱.技術名稱」作為命名空間,若類別庫較大,可以將「技術名稱」分為更多層級。 • 舉例來說,微軟(公司名稱)有C#與VB兩種技術,故規劃了兩個命名空間如下,當中各包含了許多的類別。 • Microsoft.CSharp 命名空間 • Microsoft.VisualBasic 命名空間

  44. 5.2 命名空間 • 但單純如此規劃,可能會發現有些類別會在Microsoft.VisualBasic 命名空間中重複或因為要突顯某些類別的特殊用途,故而又出現下列幾個命名空間。 • Microsoft.VisualBasic.FileIO 命名空間 • Microsoft.VisualBasic.Logging 命名空間 • 在Microsoft.VisualBasic命名空間與Microsoft.VisualBasic.FileIO命名空間中若有類別名稱相同,是允許的,因為編譯器可以由完整名稱判斷出目前使用的是哪一個類別。 • 但在同一命名空間中則不允許出現相同名稱的類別。 • 事實上,在.NET Framework中允許以完整名稱宣告物件變數的型別,如此可以避免類別名稱相同。但大多數時候,為了方便,我們並不會這樣做。

  45. 5.2 命名空間 • 【註】請注意,微軟會將類別編譯為組件,在Java中,類別庫是以目錄為單位,但.NET Framework並非如此 • 因此,一個命名空間的所有類別可能被切割到不同的組件。而一個組件也可能包含了多個命名空間的類別。 • 因此當您在線上說明查閱某個命名空間時,它並不會說明該命名空間被分配到哪一個組件,而是當您查閱某個類別時,它才會說明該類別屬於哪一個命名空間及該類別被分配到哪一個組件中。 • 例如System.Web.UI.WebControls.Button類別被分配到System.Web(也就是System.Web.dll檔)組件中,而System.Web.UI.PostBackOptions類別也被分配到System.Web(System.Web.dll檔) 組件中,但這兩個類別並非屬於同一個命名空間。 • 至於System.Web.dll檔一般位於\WINDOWS\Microsoft.NET\Framework\v4.0.30319\目錄中 • (最後一層子目錄會因版本而不同)。

  46. 5.2.1 .NET Framework的類別 • 使用命名空間的類別時,應該要先引入命名空間或類別,.NET Framework包含了許多的命名空間,並且在開發ASP.NET時,會自動引入的命名空間如下表 • 這代表我們不需要引入下列命名空間,就可以直接使用其內的所有類別:

  47. 5.2.1 .NET Framework的類別

  48. 5.2.1 .NET Framework的類別 • 繼承階層架構的根:Object • 在.NET Framework的規劃中,所有的類別都應該有一個父類別,對於沒有父類別的類別而言,它的父類別就是System.Object類別。 • 換句話說,所有的類別都是System.Object類別的子孫類別。

  49. 5.2.2 Microsoft.VisualBasic命名空間 • 當我們使用VB語法開發ASP.NET程式時,除了表5-1所列之命名空間內的類別可使用外,Microsoft.VisualBasic命名空間內的類別也可以使用。 • 例如我們在第4章中,為了判斷字串內容是否為正整數,使用了IsNumeric與InStr兩個程序 • 而這兩個程序則分別是Microsoft.VisualBasic.Information類別與Microsoft.VisualBasic.Strings的共用方法。 • 但是如果您使用的是C#語法開發ASP.NET程式,則無法使用IsNumeric程序,除非您先明確引入Microsoft.VisualBasic命名空間。

More Related