博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅析C#中new、override、virtual关键字的区别
阅读量:4325 次
发布时间:2019-06-06

本文共 3195 字,大约阅读时间需要 10 分钟。

Virtual :

virtual 关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。

默认情况下,方法是非虚拟的。不能重写非虚方法。

virtual 修饰符不能与 static、abstract, private 或 override 修饰符一起使用。

 

Override :

override 方法提供从基类继承的成员的新实现。

由 override 声明重写的方法称为重写基方法。重写的基方法必须与 override 方法具有相同的签名。

重写的基方法必须是vitural,override,abstract类型的 ,不能重写非虚方法或是静态方法。

所以override不能与vitural,new,static同时使用。

override 属性,声明必须指定与继承属性完全相同的访问修饰符、类型和名称,并且被重写的属性必须是 virtual、abstract 或 override 的。(注意:这里是属性,不是字段,字段是不能被重写的)。

 

New :

用于创建对象和调用构造函数。

使用 new 修饰符可以显式隐藏从基类继承的成员。

若要隐藏继承的成员,请使用相同名称在派生类中声明该成员,并用 new 修饰符修饰它。

 

  

//下面用代码来说明: //By Alan Liao 2008-10-22    class Father    {        protected string firstname;        protected string lastname;              public Father()        {        }        public Father(string firstname, string lastname)        {            this.firstname = firstname;            this.lastname = lastname;        }        public virtual void GetFullName()        {            Console.WriteLine("Father:{0}   {1}", firstname, lastname);        }    }    class Son : Father    {        public int age;        public Son() : base() { }        public Son(string firstname, string lastname,int age):base(firstname,lastname)          {            this.age = age;        }        //public new void GetFullName()        public override void GetFullName()        {            Console.WriteLine("Son:{0}  {1}", firstname, lastname);        }    }    class Program    {        static void Main(string[] args)        {            Father father = new Father("Alan", "Liao");            Father son1 = new Son("Little Alan ", "Liao",20);            father.GetFullName();            son1.GetFullName();            Console.ReadLine();        }    }

 

本代码输出:

Father:Alan Liao

Son:Little Alan Liao

若将36行换成35行(即将Override换成New)

输出结果为:

(其实代码中的virtual,override 都可以去掉,可以编译,运行通过,但是会有Warnning,结果同下)

Father:Alan Liao

Father:Little Alan Liao

 

可见结果不一样。

Father a=new Son();

使用new声明的方法使用的仍是父类方法,而override声明的方法使用的是子类中的方法。

其实,根本原因是对象a会优先调用子类中的方法,如果子类没有重写父类的方法,a 就调用父类中的方法。 

override 说明的是虚方法,在子类中覆盖父类中的方法。

new则不是,new是给子类新增加了一个函数,可以说除了函数名字相同以外,它跟基类里面的这个同名函数没有任何关系。相当于重新新建了一个方法,从而隐藏了父类方法.

  

其它:

在 C# 中,派生类可以包含与基类方法同名的方法。

(1)基类方法必须定义为 

(2)如果派生类中的方法前面没有  或  关键字,则编译器将发出警告,

    该方法将有如存在 new 关键字一样执行操作。

(3)如果派生类中的方法前面带有 new 关键字,则该方法被定义为独立于基类中的方法。

(4)如果派生类中的方法前面带有 override 关键字,则派生类的对象将调用该方法,而不是调用基类方法。

(5)可以从派生类中使用 base 关键字调用基类方法。

(6) overridevirtual 和 new 关键字还可以用于属性、索引器和事件中。

 

补充:

class Father{    public virtual void PrintName()    {        Console.WriteLine("Father:{0}", this.GetType().ToString());    }}class Son : Father{    //public new void PrintName()    public override void PrintName()    {        Console.WriteLine("Son:{0}", this.GetType().ToString());    }}class Program{    static void Main(string[] args)    {        Father father = new Father();        Father son = new Son();        father.PrintName();        son.PrintName();        Console.ReadLine();    }}

 

以上程序的运行结果:(其中myNamespace是这两个类的命名空间)

Father:myNamespace.Father

Son:myNamespace.Son

 

如果在第11行将override换成new,那么运行结果如下:

Father:myNamespace.Father

Father:myNamespace.Son

从上可以看出虽然调用的是Father类中的方法,但是this.GetType()返回的是myNamespace.Son类型,所以在Father中的PrintName()方法中的this指的是调用该方法的对象,而不是定义该方法的对象。

转载于:https://www.cnblogs.com/xyz1220/p/7286143.html

你可能感兴趣的文章
jQuery基础--选择器
查看>>
减小服务器负担,Apache启用mod_expires模块
查看>>
20.Mybatis之逆向工程
查看>>
mysql 中时间和日期函数应用
查看>>
自动化测试-selenium初始化Driver参考
查看>>
mybatis使用collection查询集合属性规则
查看>>
linux查看文件的编码格式的方法 set fileencoding PYTHON
查看>>
Git 问题:SSL certificate problem: self signed certificate
查看>>
安全测试
查看>>
作业代码
查看>>
网络抓取功能实现 将获取的结果进行过滤并写入到TXT文档中
查看>>
暑假集训-7.31总结
查看>>
安卓:动态注册广播
查看>>
Oracle系列--基础理论
查看>>
广州.NET微软技术俱乐部微信群各位技术大牛的blog
查看>>
npm安装vue-cli时速度慢,fetchMetadata经常卡住并报异常
查看>>
POJ:1703-Find them, Catch them(并查集好题)(种类并查集)
查看>>
HDU:5040-Instrusive
查看>>
校验器
查看>>
thread/threading——Python多线程入门笔记
查看>>