zoukankan      html  css  js  c++  java
  • [转载]C#中的new修饰符以及多态

    new关键字可以作为运算符,创建一个对象,也可以做修饰符;

    作修饰符的时候,官方文档的解释为:

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

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

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

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

    假设有如下代码: 

    View Code -Interkey
     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和多态的关系:

    View Code -Interkey
     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

  • 相关阅读:
    axios实现跨域及突破host和referer的限制
    视频测试URL地址
    微信小程序 自定义导航栏 自动获取高度 写法
    解决flex布局宽度超出时,子元素被压缩的问题
    子组件向父组件通信与父组件向子组件通信
    时间截止器
    arguments
    改变this指向&闭包特性
    ES6扩展——箭头函数
    ES6扩展——函数扩展之剩余函数
  • 原文地址:https://www.cnblogs.com/Interkey/p/2866305.html
Copyright © 2011-2022 走看看