zoukankan      html  css  js  c++  java
  • 浅析C#中new、override、virtual关键字的区别

    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)基类方法必须定义为 virtual

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

        该方法将有如存在 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指的是调用该方法的对象,而不是定义该方法的对象。

  • 相关阅读:
    中国SNS用户体验设计分析和互动性浅析
    jQuery的运行机制和设计理念
    Web前端工程师如何给自己定位?
    用户体验这点事儿
    css selection改变文字反选的背景颜色
    HTTP 状态代码
    [翻译]导致网站可用性差的十个最常见问题
    前端开发中的一些用户体验细节
    SQL的行转列问题
    ASP.NET动态添加文本框参考做法
  • 原文地址:https://www.cnblogs.com/xyz1220/p/7286143.html
Copyright © 2011-2022 走看看