new关键字可以作为运算符,创建一个对象,也可以做修饰符;
作修饰符的时候,官方文档的解释为:
Used to hide an inherited member from a base class member.
中文意思为隐藏从基类中继承了的成员。
那么如何理解“隐藏是”的意思?
本人以为,这里的隐藏是指隐藏了从基类中继承了的成员,可以理解为,虽然子类从基类中继承了该成员,但是该成员对子类不可见,或者说子类不认为该成员是从父类继承得来的,而认为是自己新建的一个成员,和父类的一点关系也没有。
假设有如下代码:
1 class Program 2 2 { 3 3 static void Main(string[] args) 4 4 { 5 5 Son s = new Son(); 6 6 s.methodB(); 7 7 Console.ReadLine(); 8 8 } 9 9 } 10 10 11 11 public class Father 12 12 { 13 13 public virtual void methodA() 14 14 { 15 15 Console.WriteLine("Father.methodA"); 16 16 } 17 17 18 18 public virtual void methodB() 19 19 { 20 20 methodA(); 21 21 } 22 22 } 23 23 24 24 public class Son : Father 25 25 { 26 26 public new void methodA() 27 27 { 28 28 Console.WriteLine("Son.methodA"); 29 29 } 30 30 }
当运行 s.methodB();的时候,会去运行s中从Father继承了的methodA,但是程序发现Son类中并没有从Father中继承methodA方法(虽然Son类中有一个methodA方法,但是程序不认为该方法是从Father中继承的)。因此,在这种情况下,程序会根据继承链,寻找离Son类最近的基类,找到Father,然后再调用Father类中的methodA,因此程序输出的是Father.methodA。
如果将new改成override,则得到的就是Son.methodA。
因此可以得出一些总结,override和new都是根据对象的运行时类型调用该类型的方法。当方法是override修饰的,则调用该方法。但是当方法是new修饰的,则认为该方法并没有被继承,转而根据继承链去找离该对象最近的基类的方法。
继承虚函数时,无论使用new修饰还是override,都是一种多态的体现。多态的概念简单的说就是A物体表现出B物体的行为,性质。在计算机科学中,多态是编程语言的一种特性,它允许不同类型的数据可以通过一个统一的接口进行操作。多态通常分为编译时多态和运行时多态。运行时的多态性就是指直到系统运行时,才根据实际情况决定实现何种操作。
无论使用new还是override,都是在运行的时候才确定要调用哪个方法。再看下面的例子,可以更好的理解new和override和多态的关系:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 string input = Console.ReadLine(); 6 Person p = null; 7 if (input == "0") 8 { 9 p = new GrandFather(); 10 } 11 else if (input == "1") 12 { 13 p = new Father(); 14 } 15 else if (input == "2") 16 { 17 p = new Son(); 18 } 19 else 20 { 21 p = new Person(); 22 } 23 p.methodA(); 24 Console.ReadLine(); 25 } 26 } 27 28 public class Person 29 { 30 virtual public void methodA() 31 { 32 Console.WriteLine("Person.methodA"); 33 } 34 } 35 36 public class GrandFather : Person 37 { 38 override public void methodA() 39 { 40 Console.WriteLine("GrandFather.methodA"); 41 } 42 } 43 public class Father : GrandFather 44 { 45 public override void methodA() 46 { 47 Console.WriteLine("Father.methodA"); 48 } 49 } 50 51 public class Son : Father 52 { 53 public new void methodA() 54 { 55 Console.WriteLine("Son.methodA"); 56 } 57 }
p声明为Person类的对象,但是根据输入参数的不同,p在运行时表现为各自不同的类型。
当输入0的时候,p表现为GrandFather类,调用GrandFather类中继承的methodA方法,输出GrandFather.methodA
当输入1的时候,p表现为Father类,调用Father类中继承的methodA方法,输出Father.methodA
当输入2的时候,p表现为Son类,调用Son类中继承的methodA方法,但是由于Son类中methodA方法是new修饰的,因此认为Son类中继承的methodA方法被隐藏了,不可见了,因此根据继承链,调用Father类中的methodA,因此也是输出 Father.methodA
当输入其他字符时,p表现为Person类,调用Person类中继承的methodA方法,输出Person.methodA。
本文出自 “一只博客” 博客,并进行了适量修改。
本文出自 “一只博客” 博客,请务必保留此出处http://cnn237111.blog.51cto.com/2359144/1120179