深圳外贸网站建设设计公司,微信自己怎么弄小程序,福州网站制作外包,301跳转wordpressC#支持单继承#xff0c;说到继承就不得不说new#xff0c;virtual和override这三个关键词#xff0c;灵活正确的使用这三个关键词#xff0c;可以使程序结构更加清晰#xff0c;代码重用性更高。 以下是msdn中对new#xff0c;virtual和override的定义#xff1a; … C#支持单继承说到继承就不得不说newvirtual和override这三个关键词灵活正确的使用这三个关键词可以使程序结构更加清晰代码重用性更高。 以下是msdn中对newvirtual和override的定义 使用 new 修饰符显式隐藏从基类继承的成员。若要隐藏继承的成员请使用相同名称在派生类中声明该成员并用 new 修饰符修饰它。 virtual 关键字用于修改方法或属性的声明在这种情况下方法或属性被称作虚拟成员。虚拟成员的实现可由派生类中的重写成员更改。调用虚方法时将为重写成员检查该对象的运行时类型。将调用大部分派生类中的该重写成员如果没有派生类重写该成员则它可能是原始成员。默认情况下方法是非虚拟的。不能重写非虚方法。 不能将virtual 修饰符与以下修饰符一起使用 static abstract override 使用 override 修饰符来修改方法、属性、索引器或事件。重写方法提供从基类继承的成员的新实现。由重写声明重写的方法称为重写基方法。重写基方法必须与重写方法具有相同的签名。不能重写非虚方法或静态方法。重写基方法必须是虚拟的、抽象的或重写的。 重写声明不能更改虚方法的可访问性。重写方法和虚方法必须具有相同的访问级修饰符。 不能使用下列修饰符修改重写方法 new static virtual abstract 重写属性声明必须指定与继承属性完全相同的访问修饰符、类型和名称并且重写属性必须是虚拟的、抽象的或重写的。 可以稍微归纳一下 1. 对于基类中说明为虚的方法则必须在派生类中new或者override注对于基类的虚方法虽然你在派生类中即不new也不override但系统还是会提示你添关键字。否则系统将视其为隐藏。我们的意思是一样的但总觉得明明确确写上关键字还是好些。 2. 如果用基类指针指向派生类对象的方式动态匹配的源动力是virtual,而new和override都会阻止这种向下寻求匹配的行为所以要使虚函数的性质得已保持下去就要隐藏基类的虚方法即在派生类中隐藏基类虚方法时同时加以virtual关键字使在多层次继承中能够调用到对象自身的版本。 3.在多层次继承中三个关键字使用次序有限定new没有使用前提即不管是普通方法、虚方法还是重写了的方法。virtual的使用在它的基类不能有函数签名相同的方法否则系统将提示添加new即隐藏基类中的方法。virtual一般只出现一次除非要在子类中隐藏父类的虚方法。 override的使用是为了重写基类虚方法。 上面的描述都很抽象对于初学者可能不好理解下面我将用示例来说明这三个用法和区别此程序在vs2005下调试通过。其中有三个类分别 为基类BaseClass继承类InheritClass和继承类的继承类GrandsonClass代码分别如下 //BaseClass.csnamespace NewVirtualOverride{ class BaseClass { public BaseClass() { } publicvoid Print() { Console.WriteLine(BaseClassPrint); } }}//InheritClass.csnamespace NewVirtualOverride{ class InheritClass : BaseClass { public InheritClass():base() { } publicvoid Print() { Console.WriteLine(InheritClassPrint); } }}//GrandsonClass.csnamespace NewVirtualOverride{ class GrandsonClass : InheritClass { public GrandsonClass():base() { } publicvoid Print() { Console.WriteLine(GrandsonClassPrint); } }}//最后是主程序Program:namespace NewVirtualOverride{ class Program { staticvoid Main(string[] args) { BaseClass baseclass new BaseClass(); baseclass.Print(); InheritClass inheritClass new InheritClass(); inheritClass.Print(); Console.ReadLine(); } }} 运行这个程序会得到如下的结果 BaseClassPrint InheritClassPrint 其实细心的朋友在编译这个项目时会发现出现了如下的警告提示 class InheritClass:BaseClass{ public InheritClass():base() {} //New Virtual Override InheritClass.Print()隐藏了继承的成员 //New Virtual Override BaseClass.Print()。如果是刻意隐藏请使用newpublicvoid Print() { Console.WriteLine(Hello); }} 大致意思是说基类和继承类中有相同名字的方法请在继承类中使用new来重新定义方法。这里的微妙之处在于无论我们是隐式地指定new方法还是显式的指定new方法都与基类中的方法无关在名称、原型、返回类型和访问修饰符方面都无关。 我们将程序中的Print()方法都变成new public void Print()后上面的异常就不会发生了。再次运行程序结果不变。new就是继承类使用与基类方法相同的名字对基类方法的重写。 下面我们看看virtual 和 override的搭配使用方法。 把BaseClass.cs改变如下public virtual void Print(); 把InheritClass.cs改变如下public override void Print(); 运行程序结果如下 BaseClassPrint InheritClassPrint 虽然结果与用new修饰符差不多但是其中的含意可不同new是继承类对基类方法的重写而在继承类中产生新的方法这时基类方法和继承方法之间没有任何的关系了可是override就不同了它也是对基类中方法的重写但此时只是继承类重写了一次基类的方法。可以参考下面的例子来加深理解。 将Program.cs改变如下 BaseClass baseclass new BaseClass();baseclass.Print();InheritClass inheritClass new InheritClass();inheritClass.Print();BaseClass bc new InheritClass();bc.Print(); 分别运行用new修饰和用virtual/override修饰的程序其结果如下 用new修饰的结果 BaseClassPrint InheritClassPrint BaseClassPrint 用virtual/override修饰的结果 BaseClassPrint InheritClassPrint InheritClassPrint 从上面的结果可以看出在用new修饰的情况下虽然bc是用InheritClass创建的实例但是bc.Print()打印的还是BaseClassPrint因为此时BaseClass和InheritClass中的Print已经是互不相同没有关系的两个方法了而在virtual/override修饰的情况下bc调用的Print方法已经被其子类override了所以就打印了InheritClassPrint。 最后我们再说说关键词之间的搭配关系上面已经给出了virtual和override不兼容的几个关键词这里就不重复了。我要说的是new和virtual在声明函数时其实可以一块使用。因为这个函数是新的故与其它任何new函数一样隐藏了具有相同原型的继承来的函数。因为这个函数也是虚拟的所以可以在派生类中进一步复位义这样就为这个虚拟函数建立了一个新的基级别。最后用GrandsonClass类来看看。 将GrandsonClass.cs修改如下namespace NewVirtualOverride{ class GrandsonClass : InheritClass { public GrandsonClass():base() { } publicoverridevoid Print() { Console.WriteLine(GrandsonClassPrint); } }}InheritClass.cs修改如下namespace NewVirtualOverride{ class InheritClass : BaseClass { public InheritClass():base() { } newpublicvirtualvoid Print() { Console.WriteLine(InheritClassPrint); } }}BaseClass.cs修改如下namespace NewVirtualOverride{ class BaseClass { public BaseClass() { } publicvirtualvoid Print() { Console.WriteLine(BaseClassPrint); } }}Program.cs修改如下namespace NewVirtualOverride{ class Program { staticvoid Main(string[] args) { BaseClass baseclass new BaseClass(); baseclass.Print(); InheritClass inheritClass new InheritClass(); inheritClass.Print(); BaseClass grandsonClass new GrandsonClass(); grandsonClass.Print();\ Console.ReadLine(); } }} 运行结果为 BaseClassPrint InheritClassPrint BaseClassPrint 可见在InheritClass中使用了new以后就意味着它与基类的同名方法为两个不同方法了而它又是虚拟的所以它的子类还可以继续继承BaseClass的Print()方法。 将函数声明为virtual 与将它声明为new virtual是一样的因为new仍然是默认的。所以下面的两句是相同的 public new virtual void Print(); public virtual void Print(); 那么new virtual的意义又在什么地方呢在大型的层次结构中这可能很有用比如如下的System.Windows.Form类的继承关系Object-MarshalByRefObject-Component-Control-ScrollableControl- ContainerControl。 很容易想象出将一个派生的窗体集合作为窗体对待而不是作为Object的情形。 再将Program.cs修改如下 namespace NewVirtualOverride{ class Program { staticvoid Main(string[] args) { BaseClass baseclass new BaseClass(); baseclass.Print(); InheritClass inheritClass new InheritClass(); inheritClass.Print(); BaseClass grandsonClass1 new InheritClass(); grandsonClass1.Print(); InheritClass grandsonClass2 new GrandsonClass(); grandsonClass2.Print(); Console.ReadLine(); } }} 运行结果为 BaseClassPrint InheritClassPrint BaseClassPrint GrandsonClassPrint 转载于:https://www.cnblogs.com/zhcw/archive/2012/06/27/2565321.html