你真的理解 new 了吗?

  开篇先提几个问吧,如果你对这些问题都清楚了,那说明对于 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("======基类构造完成=============
");
47 
48             /*调用本身及基类的构造方法  注意:子类继承了基类之后 在new 时会先调用基类的构造方法再调用子类的
49              而调用析构函数的顺序则相反,先调用子类的析构函数再调用基类的*/
50             Number number = new Number();
51             Console.WriteLine("======子类构造完成=============
");
52 
53             baseNumber.ShowInfo(); //调用基类方法
54             baseNumber.ShowNumber(); //调用基类方法 
55             Console.WriteLine("==========基类方法调用完毕============
");
56 
57             number.ShowInfo(); //调用子类的方法
58             number.ShowNumber(); //调用子类的方法因为重写了基类的方法
59             Console.WriteLine("==========子类方法调用完毕============
");
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 没有细心了解过

希望本文能带给需要的朋友一点小小的收获,如果您觉得本文对您有那么一点点帮助还望小小的推荐一下啊,您的推荐将是我源源不断的写作力~!!

原文地址:https://www.cnblogs.com/zery/p/3267020.html