对于 子类和基类中 方法的重写 override 和覆盖 new

之前  写接口实现的时候 就遇到   子类中写的方法   与基类中同名 

然后系统推荐使用new  或者使用  override  

但是  只是警告  并有没有编译不通过

今天看了下代码   发现  陈亮的在基类中 直接使用 virtual     修饰方法    、

不解  于是上网搜 看到msdn   只是基本概念的介绍   还是不太理解   他们直接具体的差别

然后是上网搜  

网上都说  覆盖就是重新    不赞同 

如果真要是这样    为了让子类继承    就专门 基类写一个 virtual  并且 子类加个  override 

 这比  基类什么都不加  直接在子类new  麻烦的多啊  

于是上完搜

发现 这个人 在他们之间的区别上   把握的很好

重写

用关键字 virtual 修饰的方法,叫虚方法。可以在子类中用override 声明同名的方法,这叫“重”。相应的没有用virtual修饰的方法,我们叫它实方法
会改变父类方法的功能。
看下面演示代码:
#region

publicclassC1
{
publicvirtualstringGetName()
{
return"徐明祥";
}
}

publicclassC2 : C1
{
publicoverridestringGetName()
{
return"xumingxiang";
}
}

C1 c1 = newC1();
Console.WriteLine(c1.GetName());//输出“徐明祥”

C2 c2 = newC2();
Console.WriteLine(c2.GetName());//输出“xumingxiang”

//重点看这里

C1 c3 = newC2();
Console.WriteLine(c3.GetName());//输出“xumingxiang” 

#endregion
覆盖
在子类中用 new关键字修饰 定义的与父类中同名的方法,叫覆盖
覆盖会改变父类方法的功能。
看下面演示代码:     
#region覆盖

publicclassC1
{
publicstringGetName()
{
return"徐明祥";
}
}

publicclassC2 : C1
{
publicnewstringGetName()
{
return"xumingxiang";
}
}

C1 c1 = newC1();
Console.WriteLine(c1.GetName());//输出“徐明祥”

C2 c2 = newC2();
Console.WriteLine(c2.GetName());//输出“xumingxiang”

//重点看这里,和上面的重作比较

C1 c3 = newC2();
Console.WriteLine(c3.GetName());//输出“徐明祥” 

#endregion

总结

1:管是重还是覆盖会影响父类自身的功能(废话,肯定的嘛,除非代码被改)。

2:当用子类创建父类的时候,如 C1 c3 = newC2(),重会改变父类的功能,即调用子类的功能;而覆盖会,仍然调用父类功能。

3:虚方法、实方法都可以被覆盖new),抽象方法,接口 可以。

4:抽象方法,接口,标记为virtual的方法可以被重(override),实方法可以。

5:重使用的频率比较高,实现多态;覆盖用的频率比较低用于对以前无法修改的类进行继承的时候。

另外的区别 

使用override  可以在虚函数列表 中  查找到 virtual   不写则找不到

翻看C# 高级编程  上边讲到   重写 override 是为了实现多态//人家做的目的   就是为了 实现多态用的 目的性很强  自基类方法写好的时候就告诉你 这事为了多态 

而 new 的这种写法  是为了把原来的隐藏起来

 这种说法  也许能够解释 上边的总结   第二条    

换种说法   就是一次覆盖(override ) 永久不变

一次new   只是把原来的影藏了

对于 写不写 new 这点   (都能编译的通过  ,不写的话  会给警告)

于是觉得没问题 

于是去问博然 

博然告诉我  //这点上  我觉得 博然的理论性 显然要强于中超  O(∩_∩)O哈哈~

他说  如果 你也不写  new  我也不new      我们两家公司的在合作的时候     就不能强命名(用 key 来标识

这样  两家公司就不好区分了

所以 加不加new 的区别    就是  另外开辟地址 用来 以便用来区分

原文地址:https://www.cnblogs.com/jilodream/p/4222737.html