C#中virtual,override,new的区别是什么

virtual
  用于父类中,声明某方法可以重写,该方法不能是static;
override(覆盖继承)
  用于子类中,重写父类中用virtual/override/abstract关键字声明的方法;
new(隐藏继承)
  用于子类中,可修饰父类中有或无virtual声明的方法;
  如果在父类中有与父类同名同参的方法时,C#会隐式在子类前添加一个new关键字。

【区别】override与new
  当将一个子类实例赋值给父类实例,在子类实例与父类实例中分别调用该方法时:使用override修饰的都将调用子类方法,而使用new修饰的会分别调用子类方法和父类方法。
  New和Override这两个关键字是互斥的。不可以同时使用。


【区别】virtual与abstract
  virtual:用于父类中声明该方法可被重写。
  abstract:只能用在抽象类中声明抽象方法,本身不能实现任何功能(因此必须在子类中override),不能实例化。
  两者除了在子类中同样可以用override重写这个相同点之外,没有其他关系。
 

 

-------------------------------------------------------------------------------------------------------------------

C#支持单继承,说到继承就不得不说new,virtual和override这三个关键词,灵活正确的使用这三个关键词,可以使程序结构更加清晰,代码重用性更高。
    

      以下是msdn中对new,virtual和override的定义:

      使用 new 修饰符显式隐藏从基类继承的成员。若要隐藏继承的成员,请使用相同名称在派生类中声明该成员,并用 new 修饰符修饰它。
      virtual 关键字用于修改方法或属性的声明,在这种情况下,方法或属性被称作虚拟成员。虚拟成员的实现可由派生类中的重写成员更改。调用虚方法时,将为重写成员检查该对象的运行时类型。将调用大部分派生类中的该重写成员,如果没有派生类重写该成员,则它可能是原始成员。默认情况下,方法是非虚拟的。不能重写非虚方法。
      virtual 修饰符不能将与以下修饰符一起使用:
      static    abstract    override
      使用 override 修饰符来修改方法、属性、索引器或事件。重写方法提供从基类继承的成员的新实现。由重写声明重写的方法称为重写基方法。重写基方法必须与重写方法具有相同的签名。不能重写非虚方法或静态方法。重写基方法必须是虚拟的、抽象的或重写的。
      重写声明不能更改虚方法的可访问性。重写方法和虚方法必须具有相同的访问级修饰符。
    
      override不能使用下列修饰符修改重写方法:
      new   static    virtual   abstract
      重写属性声明必须指定与继承属性完全相同的访问修饰符、类型和名称,并且重写属性必须是虚拟的、抽象的或重写的。
     
可以稍微归纳一下:
      1. 对于基类中说明为虚的方法则必须在派生类中new或者override(注:对于基类的虚方法,虽然你在派生类中即不new也不override,但系统还是会提示你添关键字。否则系统将视其为隐藏。我们的意思是一样的,但总觉得明明确确写上关键字还是好些)。

      2. 如果用基类指针指向派生类对象的方式,动态匹配的源动力是virtual,而new和override都会阻止这种向下寻求匹配的行为,所以要使虚函数的性质得已保持下去,就要隐藏基类的虚方法,即在派生类中隐藏基类虚方法时,同时加以virtual关键字,使在多层次继承中能够调用到对象自身的版本。注:如 public new virtual  方法名()

      3.在多层次继承中,三个关键字使用次序有限定。
    new没有使用前提,即不管是普通方法、虚方法还是重写了的方法。

    virtual的使用,在它的基类不能有函数签名相同的方法,否则系统将提示添加new,即隐藏基类中的方法。virtual一般只出现一次,除非要在子类中隐藏父类的虚方法。
override的使用是为了重写基类虚方法。
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
           
            B b = new B();
            A a = b;
            B c = (B)a;
            OK(b);
            
            
        }
        public static void OK(A a)
        {
            a.Soft();
        }
    }
    class A
    {
        private string p_name;
        private string p_sex;
        public A()
        {
            this.p_name = "李世民";
            this.p_sex = "男";
        }
        public A(string str_name,string str_sex) 
        {
            this.p_name = str_name;
            this.p_sex = str_sex;
        }
        public void M()
        {
            Console.WriteLine("姓名:"+this.p_name);
            Console.WriteLine("性别:"+this.p_sex);
        }
        public virtual void Soft()
        {
            Console.WriteLine("我是A类里面的soft方法");
        }
        public void F()
        {
            Console.WriteLine("我是A类里的F方法");
        }
    }
    class B :A{
        private string 朝代;
        public B():base()
        {
            this.朝代 = "大唐王朝";
        }
        public B(string s_name, string s_sex, string cd)
            : base(s_name, s_sex)
        {
            this.朝代 = cd;
        }
        public new void M()
        {
            base.M();
            Console.WriteLine("朝代:"+this.朝代);
            
        }
        public override void Soft()
        {
            Console.WriteLine("我是B类里的Soft方法");
        }
        public new void F()
        {
            Console.WriteLine("我是B类里的F方法");
        }

    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值