热门IT资讯网

C#中的new修饰符以及多态

发表于:2024-11-26 作者:热门IT资讯网编辑
编辑最后更新 2024年11月26日,new关键字可以作为运算符,创建一个对象,也可以做修饰符,作修饰符的时候,官方文档的解释为:Used to hide an inherited member from a base class mem

new关键字可以作为运算符,创建一个对象,也可以做修饰符,作修饰符的时候,官方文档的解释为:

Used to hide an inherited member from a base class member.

中文意思为隐藏从基类中继承了的成员。

那么如何理解"隐藏是"的意思?

本人以为,这里的隐藏是指隐藏了从基类中继承了的成员,可以理解为,虽然子类从基类中继承了该成员,但是该成员对子类不可见,或者说子类不认为该成员是从父类继承得来的,而认为是自己新建的一个成员,和父类的一点关系也没有。

假设有如下代码:

  1. public class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. Son s = new Son();
  6. s.methodB();
  7. }
  8. }
  9. public class Father
  10. {
  11. public virtual void methodA()
  12. {
  13. Console.WriteLine("Father.methodA");
  14. }
  15. public virtual void methodB()
  16. {
  17. methodA();
  18. }
  19. }
  20. public class Son : Father
  21. {
  22. public new void methodA()
  23. {
  24. Console.WriteLine("Son.methodA");
  25. }
  26. }

当运行 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. public 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. p.methodA();
  20. }
  21. }
  22. public class Person
  23. {
  24. virtual public void methodA()
  25. {
  26. Console.WriteLine("Person.methodA");
  27. }
  28. }
  29. public class GrandFather : Person
  30. {
  31. override public void methodA()
  32. {
  33. Console.WriteLine("GrandFather.methodA");
  34. }
  35. }
  36. public class Father : GrandFather
  37. {
  38. public override void methodA()
  39. {
  40. Console.WriteLine("Father.methodA");
  41. }
  42. }
  43. public class Son : Father
  44. {
  45. public new void methodA()
  46. {
  47. Console.WriteLine("Son.methodA");
  48. }
  49. }

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。

0