你真的理解 new 了嗎?

Zery發表於2013-08-18

  開篇先提幾個問吧,如果你對這些問題都清楚了,那說明對於 new  這個關鍵字已經掌握得很好了,也不再需要花時間來閱讀本文了,

1   new  一個class  與 new   一個Struct有什麼不同?

2   new 在.net中有幾種用法?

3   new 運算子 是否可以過載?

4   new 一個基類中的方法,與override一個基類中的方法有什麼不同?

5   int i 與 int i = new int();有何不同?

答案會在文章結尾給出!

  首先來簡單介紹下new 

 做為修飾符的new: 用於向基類成員隱藏繼承成員

 做為運算子的new: 用於呼叫基類的建構函式 和 建立物件並分配記憶體

 

下面這段程式碼如果你能夠看出結果說明你對於new 的掌握已經很不錯了,因為在各種面試中對於new的考題好像不曾缺過,如果你懂了那麼在面試中那就是小菜了

 1 class BaseNumber
 2     {
 3         public static int i = 123;
 4 
 5         public BaseNumber()
 6         {
 7             Console.WriteLine("這是基類的構造方法{0}", i.ToString());
 8         }
 9 
10         public virtual void ShowNumber()
11         {
12             Console.WriteLine("基類ShowNumber方法{0}", i.ToString());
13         }
14 
15         public virtual void ShowInfo()
16         {
17             Console.WriteLine("基類的ShowInfo方法{0}", i.ToString());
18         }
19     }
20 
21     class Number : BaseNumber
22     {
23         public new static int i = 456;
24 
25         public Number()
26         {
27             Console.WriteLine("這子類的構造方法{0}", i.ToString());
28         }
29 
30         public override void ShowNumber()
31         {
32             Console.WriteLine("子類ShowNumber的方法{0}", i.ToString());
33         }
34 
35         public new virtual void ShowInfo()//因為有了new 關鍵字隱藏了基類中的成員會不會提示任何警告
36         {
37             Console.WriteLine("子類的ShowInfo方法{0}", i.ToString());
38         }
39     }
40 
41     class Program
42     {
43         private static void Main(string[] args)
44         {
45             BaseNumber baseNumber = new BaseNumber(); //呼叫本身的構造方法
46             Console.WriteLine("======基類構造完成=============\n");
47 
48             /*呼叫本身及基類的構造方法  注意:子類繼承了基類之後 在new 時會先呼叫基類的構造方法再呼叫子類的
49              而呼叫解構函式的順序則相反,先呼叫子類的解構函式再呼叫基類的*/
50             Number number = new Number();
51             Console.WriteLine("======子類構造完成=============\n");
52 
53             baseNumber.ShowInfo(); //呼叫基類方法
54             baseNumber.ShowNumber(); //呼叫基類方法 
55             Console.WriteLine("==========基類方法呼叫完畢============\n");
56 
57             number.ShowInfo(); //呼叫子類的方法
58             number.ShowNumber(); //呼叫子類的方法因為重寫了基類的方法
59             Console.WriteLine("==========子類方法呼叫完畢============\n");
60 
61             BaseNumber num = new Number(); //會呼叫基類與子類的構造方法(先調基類再調子類)
62             num.ShowInfo(); //此時為基類的例項所以會呼叫基類的方法
63             num.ShowNumber(); //被子類重寫所以呼叫子類的方法
64 
65             Console.ReadKey();
66         }
67     }

 

 

以上程式碼 回答了

 第2 題 “new 在.net中有幾種用法或者說用處的” 一部分:建立新物件,及隱藏基類中的方法 

第4 題  new 一個基類中的方法,與override基類中的方法有什麼不同?  

new一個基類中的方法並在子類中呼叫時,不會呼叫基類的方法,因為基類中的方法被隱藏了

new 關鍵字用於隱藏基類中的成員,如果子類中有一個方法與基類中的方法完全一致且沒有加new關鍵字時,編輯器會提示警告

The keyword new is required on 'MyDerivedC.x' because it hides inherited member 'MyBaseC.x'.

 

而Override則是重寫基類中的方法,

 

而對於這一段程式碼我自己也不是特別理解但我猜測是這樣的,如有不對還請各位指出  

BaseNumber num = new Number();

先說說這段程式碼的執行過程 new Number()時因為繼承了基類BaseNumber所以會先呼叫BaseNumber的建構函式,

然後呼叫Number的建構函式,從結果圖可以看到這個過程,然後將例項化後的子類賦給基類在這個過程中應該存在一個隱式的轉換 類似於

BaseNumber num = new Number() as BaseNumber; 所以最終例項化的還是基類!

 

下面逐個來解釋開篇的問題

1   new  一個class  與 new   一個Struct有什麼不同?

答:因為Class是引用型別,所以new 會分為兩步 1 在託管堆中分配記憶體,2 呼叫建構函式實現物件初始化

      而Struct是值型別 也是會分兩步 1 在執行緒棧中分配記憶體,2 呼叫建構函式實現物件初始化,

2   new 在.net中有幾種用法?

答:2.1 隱藏基類成員,

  2.2建立例項物件,並分配記憶體,

      2.3 做為類約束 class Generia<T> where :new () //約束類必須要有公共的參建構函式

3   new 運算子 是否可以過載? 

答:肯定是不可以的 (原因微軟FrameWork規定了)

4   new 一個基類中的方法,與override基類中的方法有什麼不同?

答:new一個基類中的方法並在子類中呼叫時,不會呼叫基類的方法,因為基類中的方法被隱藏了

      而Override則是重寫基類中的方法,在呼叫基類方法時會自動去子類中找到被Override的方法 

5   int i 與 int i = new int();有何不同?

 答: 在.net Framework中所有的值型別都會自動初始化,也就是說int i ; 其實隱式的呼叫了其構造方法。 而int i = new int() 只不過是顯示的呼叫了構造方法。

     另外值型別記憶體是分配線上程棧上的,且不受GC控制脫離其做用域就會自動銷燬並回收記憶體空間

 

好了關於new這個最常用的關鍵字就說到這裡了,如果還有朋友發現更高深的用法,歡迎指出~本文雖然很基礎,但是還是有很多朋友對new 沒有細心瞭解過

希望本文能帶給需要的朋友一點小小的收穫,如果您覺得本文對您有那麼一點點幫助還望小小的推薦一下啊,您的推薦將是我源源不斷的寫作力~!!

 

 

相關文章