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

简介:

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.  
  10.     public class Father 
  11.     { 
  12.         public virtual void methodA() 
  13.         { 
  14.             Console.WriteLine("Father.methodA"); 
  15.         } 
  16.  
  17.         public virtual void methodB() 
  18.         { 
  19.             methodA(); 
  20.         } 
  21.     } 
  22.  
  23.     public class Son : Father 
  24.     { 
  25.         public new void methodA() 
  26.         { 
  27.             Console.WriteLine("Son.methodA"); 
  28.         } 
  29.     } 

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

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。











本文转自cnn23711151CTO博客,原文链接:http://blog.51cto.com/cnn237111/1120179 ,如需转载请自行联系原作者



相关文章
|
12月前
|
编译器 C#
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
218 65
|
安全 C#
C# 面向对象编程的三大支柱:封装、继承与多态
【9月更文挑战第17天】在C#中,面向对象编程的三大支柱——封装、继承与多态,对于编写安全、可维护、可复用的代码至关重要。封装通过访问修饰符和属性保护数据;继承允许子类继承父类的属性和方法,实现代码复用和多态;多态则提高了代码的灵活性和通用性。掌握这三大概念能显著提升C#编程能力,优化开发效率和代码质量。
143 3
|
Java 编译器 C#
C#中的override和new关键字
在 C# 中,派生类可以包含与基类方法同名的方法。 基类方法必须定义为 virtual。 如果派生类中的方法前面没有 new 或 override 关键字,则编译器将发出警告,该方法将有如存在 new 关键字一样执行操作。 如果派生类中的方法前面带有 new 关键字,则该方法被定义为独立于基类中的方法。 如果派生类中的方法前面带有 override 关键字,则派生类的对象将调用该方法,而不是调用基类方法。 可以从派生类中使用 base 关键字调用基类方法。
171 1
|
程序员 C#
C# 类实现接口(Interface) 多态 多继承
C# 类实现接口(Interface) 多态 多继承
C#之多态
C#之多态
83 0
【C#本质论 八】类-从设计的角度去认知(多态)
【C#本质论 八】类-从设计的角度去认知(多态)
161 0
|
C# 索引
【C#】【平时作业】习题-7-继承、抽象与多态
【C#】【平时作业】习题-7-继承、抽象与多态
210 0
【C#】【平时作业】习题-7-继承、抽象与多态
|
C#
30天C#基础巩固-----多态,工厂模式
30天C#基础巩固-----多态,工厂模式
158 0
30天C#基础巩固-----多态,工厂模式
|
C#
C#(二十二)之抽象方法 密封方法 base new 关键字
本篇内容记录了普通方法的隐藏(new)、base关键字、抽象类和抽象方法(abstract)、密封类和蜜蜂方法(sealed)的简单用法。
182 0
C#(二十二)之抽象方法 密封方法 base new 关键字
|
存储 数据可视化 安全
☀️ 学会编程入门必备 C# 最基础知识介绍(五)——方法、封装、继承、多态
前言👻 方法❄️ C# 中定义方法 实例 C# 中调用方法 递归方法调用 参数传递 按值传递参数 按引用传递参数 按输出传递参数 C# 封装⛄️ Public 访问修饰符 Private 访问修饰符 Protected 访问修饰符 Internal 访问修饰符 Protected Internal 访问修饰符 C# 继承⚡️ 基类和派生类 基类的初始化 C# 多重继承 C# 多态性🎄 静态多态性 函数重载 C# 运算符重载 运算符重载的实现 可重载和不可重载运算符 动态多态性 总结💬
☀️ 学会编程入门必备 C# 最基础知识介绍(五)——方法、封装、继承、多态