輕鬆學習的有效方法

才智咖 人氣:1.84W

一、靜態方法和例項方法

輕鬆學習的有效方法

靜態方法是一個特殊的成員方法,不屬於類的某一個具體的例項或物件,而屬於類本身。靜態方法不對特定例項進行操作,只能訪問類中的靜態成員。訪問靜態方法只能使用類名,而不需要建立物件,也不能使用物件名類引用,宣告靜態方法修飾符中必須有static關鍵字。

例項方法可以使用類的任何成員。呼叫例項方法時,必須使用類的例項或物件來引用。例項方法對類的某個給定的例項進行操作,在例項方法類中可以使用this來訪問例項。呼叫例項方法時,必須先建立一個物件。

簡單的說,靜態方法只能訪問靜態成員,例項方法可以訪問靜態和例項成員。之所以不允許靜態方法訪問例項成員變數,是因為例項成員變數是屬於某個物件的,而靜態方法在執行時,並不一定存在物件。同樣,因為例項方法可以訪問例項成員變數,如果允許靜態方法呼叫例項方法,將間接地允許靜態方法使用例項成員變數,這是錯誤的。基於同樣的道理,靜態方法中不能使用關鍵字this。

例一、程式設計使用靜態方法和例項方法

using System; using ric; using ; using ; using s; namespace Text { class A { int exaVar;//建立的一個為例項成員變數 static int stVar;//建立的一個靜態成員變數 void tM()//例項方法 { exaVar = 1;//等價於r=1 stVar = 1;//等價於r=1 } static void sM()//靜態方法 { //exaVar = 1;//錯誤,靜態方法不可以呼叫例項成員變數 stVar = 1;//等價於r=1 } static void Main(string[] args) { A text = new A();//建立類A的物件為text ar = 1;//物件text訪問例項成員變數 r = 1;//只能使用類訪問靜態成員變數 //r = 1;//不能使用物件text訪問靜態成員變數 ();//使用物件text訪問例項成員方法 //();//不能使用物件text訪問靜態成員方法 ();//使用類訪問靜態成員方法 eLine(ar + r); Line(); } } }

輸出的結果為:2

二、虛方法和非虛方法

若一個例項方法的宣告中含有virtual修飾符,則稱該方法為虛方法。若其中沒有virtual修飾符,則稱該方法為非虛方法。

非虛方法的實現是一成不變的,無論該方法是在宣告它的類的例項上呼叫還是在派生類的例項上呼叫,實現均相同。與此相反,虛方法的實現可以由派生類取代。取代所繼承的虛方法的實現的過程稱為重寫該方法。在虛方法呼叫中,該呼叫所涉及的那個例項執行時型別確定了要被呼叫的究竟是該方法的哪一種實現。在非虛方法呼叫中,相關的例項的編譯時型別是決定性因素。

例二、使用虛方法和非虛方法在派生類中呼叫

using System; using ric; using ; using ; using s; namespace Text { public class A { public virtual void ab()//定義的類A的虛方法 [csharp] view plaincopyprint? { eLine("這是虛方法"); } public void ac()//定義的類A的非虛方法 { eLine("這是非虛方法"); } } public class B:A//類B私有繼承類A { public override void ab()//重寫繼承的ab方法 { eLine("這是新的方法"); } public new void ac()//建立一個新的方法覆蓋原來的ac方法 { eLine("這是另一個新的方法"); } } class Program { static void Main(string[] args) { B b = new B();//建立類B的物件b A a = b;//將物件b賦值給類A的物件a ();//呼叫原ab虛方法 ();//呼叫ab方法 ();//呼叫原ac非虛方法 ();//呼叫ac方法 Line(); } } }

從輸出的結果中可以看出虛方法的實現是由派生類取代並且由它的方法實現,而非虛方法的實現是定義的類和派生類的各自由它們的方法實現。

三、虛方法和重寫方法

重寫方法用相同的簽名重寫所繼承的虛方法。虛方法宣告用於引入新方法,而重寫方法宣告則用於使現有的繼承虛方法專用化。用override宣告所重寫的那個方法稱為已重寫了的基方法。

重寫宣告和已重寫了的基方法具有相同的宣告可訪問性。換句話說,重寫宣告不能更改所對應的 虛方法的可訪問性。但是,如果已重寫的基方法是protected,並且宣告它的程式集不是包含重寫方法的程式集,則重寫方法宣告的可訪問性必須是protected。

重寫override一般用於介面的實現和繼承類的方法改寫時應注意:

(1)覆蓋的方法的標誌要和被覆蓋的方法的標誌完全匹配,才能達到覆蓋的效果

(2)覆蓋的方法的返回值必須和被覆蓋的方法的返回值一致

(3)覆蓋的方法所丟擲的異常必須和被覆蓋的方法所丟擲的異常一致,或者是其子類

(4)被覆蓋的方法不能為private,否則在其子類中只是新定義了一個方法,並沒有對其進行覆蓋

例三、建立一個虛方法並重寫這個虛方法,通過呼叫兩個方法比較結果

using System; using ric; using ; using ; using s; namespace Text { class A { public virtual void a()//建立的虛方法 { eLine("這是虛方法"); } } class B : A { public override void a() { eLine("這是重寫後的`方法"); } } class Program { static void Main(string[] args) { B b1 = new B();//建立類B的物件b1 b1.a();//呼叫重寫後的a方法 A a1 = new A();//建立類A的物件a1 a1.a();//呼叫虛方法a A a2 = b1;//將類B的物件b1賦值給類A的物件a2 a2.a();//呼叫虛方法a Line(); } } }

輸出的結果為:這是重寫後的方法

這是虛方法

這是重寫後的方法

四、外部方法(這個方法很新奇,聯想到很多)

當方法宣告包含extern修飾符時,稱該方法為外部方法。外部方法是在外部實現的,程式語言通常是使用C#以外的語言。外部方法不可以是泛型。

extern修飾符通常與DllImport屬性一起使用,從而使外部方法可以由DLL(動態連結庫)實現。執行環境可以支援其他用來提供外部方法實現的機制。當外部方法包含DllImport屬性時,該方法宣告必須同時包含一個static修飾符。

在使用DLLImport屬性時,一定要引入ropServices名稱空間,此名稱空間是提供各種各樣支援COM interop及平臺呼叫服務的成員。

例四、通過外部方法和Dlllmport屬性呼叫“”例項自定義資訊提示框的功能

using System; using ric; using ; using ; using s; using ropServices;//必須引入的名稱空間 namespace Text { class Program { [DllImport("")]//呼叫 public static extern int MessageBox(int H, string m, string c, int type);//定義的外部方法 static int Main(string[] args) { e("請輸入資訊:"); string str = Line();//接受輸入的資訊 return MessageBox(0,str,"我的資訊提示框",0);//以資訊提示框輸出 } } }

五、分部方法

若一個方法宣告中含有partial修飾符,則稱該方法為分部方法。只能講分部方法宣告為分部型別的成員,而且要遵守約束數目。分部方法有著嚴格的限制。分部方法必須在分部類或分部機構內宣告。它們必須是私有的,不能返回值,不能有輸出引數。因為任何針對沒有被實現的分部方法的呼叫都會簡單地被忽略,所以說這些限制是非常有必要的。

分部方法不能作為一個明確分配的變數,僅被程式碼生成器在處理輕量級事件的時候使用。假設使用者解析一個數據庫或者一個XML檔案,然後生成了資料類,結果會發現有數十個類,幾百個屬性以及一大堆泛型和模板檔案等。分部方法另外一個經常被用到的地方是驗證,或者讓屬性的setter去更新另一個屬性。所以如果使用者要使用產生的程式碼,或者在執行時有幾百個事件和千個方法呼叫的話(其實大多數情況下只用到了其中的一點點),就可以選擇分部方法。分部方法在宣告和使用時要比事件容易得多,如果沒有用到它們,它們就會消失。從分部方法必須是私有的限制中,

Alexander發現了該方法的不足之處,即如果使用者喜歡原資料驅動的應用,並且已經被的資料繫結所困擾時(因為沒有其他的方法可以附上原資料),那麼,將來會出現丟失資訊的可能。

例五、建立一個類的分部方法並且在另一個部分中引用

using System; using ric; using ; using ; using s; namespace Text { public partial class Program//定義的分部類 { private int _setup;//定義的欄位 public int setup//定義的方法 { set { _setup=value; } get { return _setup; } } partial void text(int t);//宣告分部方法 partial void text(int t)//實現宣告 { t += _setup; e(t); } } partial class Program { static void Main(string[] args) { Program pg = new Program();//建立類物件 pg._setup = 100;//設定屬性 (50);//呼叫方法 Line(); } } }

輸出的結果為:150

TAGS:學習