C# 虚方法、非虚方法、重写override、new,具体调用哪个方法分析
首先先看override和new的语法特征:
-
override
1. override是派生类用来重写基类中方法的;
2. override不能重写非虚方法和静态方法;
3. override只能重写用virtual、abstract、override修饰的方法;
4. 不能使用修饰符 new、static、virtual 或 abstract 来修改 override 方法。
new
1. new是派生类用来隐藏基类中的方法的;也就是说在派生类中“看不到”基类中的方法;
2. 如果要在派生类中隐藏(不是重写)基类中的方法,而没有使用new关键字,编译时会出现一个警告,提示如果是要隐藏基类中的方法,请使用new关键字【默认是new修饰的】;
3. 派生类可以隐藏基类中的虚方法,也可以隐藏基类中的普通方法。
4. 如果在派生类中用private来修饰new 方法,那么只在该派生类中隐藏了基类中的方法,在该派生类之外,相当于没有隐藏基类中的方法;
5. 如果在派生类中隐藏了基类中的方法,在该派生类的派生类中,将延续对该派生类对基类方法的隐藏。
测试结论:
- 经测试:只有类中有虚方法重写override,才会表现出运行时类型方法特征。其他无论是不是虚方法,是不是有new 修饰,是不是有override 修饰,都表现出编译时类型方法特征【即声明的类型是什么就调用什么方法】。
以下是测试方法内容:
//1、虚方法重写override,运行时类型方法特征。
//1.1、虚方法未重写,编译时【未重写派生类调用基类方法】产生装箱或转型
//1.2、虚方法重写new或没有new也没有override,编译时【重写派生类隐藏基类方法】
//2、非虚方法重写。编译时【重写派生类隐藏基类方法】
//3、非虚方法未重写,调用基类方法。编译时【未重写派生类调用基类方法】产生装箱或转型
代码

1 public class TestShape 2 { 3 public static void Main(string[] args) 4 { 5 //主要测试:1、虚方法重写override,运行时类型方法特征。 6 //1.1、虚方法未重写,编译时【未重写派生类调用基类方法】装箱或转型 7 //1.2、虚方法重写new或没有new也没有override,编译时【重写派生类隐藏基类方法】 8 //2、非虚方法重写。编译时【重写派生类隐藏基类方法】 9 //3、非虚方法未重写,调用基类方法。编译时【未重写派生类调用基类方法】装箱或转型 10 11 //1、 12 Shape shape = new Circle(); 13 shape.MethodVirtual();//circle override MethodVirtual 14 //2、编译时 15 Diamond diamond = new Diamond(); 16 diamond.Method();//Diamond default Method 17 Shape s = new Diamond(); 18 s.Method();//base Method call 19 //结论:非虚方法重写编译时 类型方法。 20 //1.2 编译时 21 diamond.MethodVirtual();//Diamond default MethodVirtual,没有使用override默认是new 22 s.MethodVirtual();//base MethodVirtual call,没有使用override默认是new 23 //3、编译时 24 Circle circle = new Circle(); 25 circle.Method();//base Method call 26 } 27 } 28 public class Shape 29 { 30 public virtual void MethodVirtual() 31 { 32 Console.WriteLine("base MethodVirtual call"); 33 } 34 public void Method() 35 { 36 Console.WriteLine("base Method call"); 37 } 38 } 39 public class Circle: Shape 40 { 41 public override void MethodVirtual() 42 { 43 Console.WriteLine("circle override MethodVirtual"); 44 } 45 } 46 public class Triangle : Shape 47 { 48 public new void MethodVirtual() 49 { 50 Console.WriteLine("Triangle new MethodVirtual"); 51 } 52 public new void Method() 53 { 54 Console.WriteLine("Triangle new Method"); 55 } 56 } 57 public class Diamond : Shape 58 { 59 //默认是使用了new关键字 60 public void MethodVirtual() 61 { 62 Console.WriteLine("Diamond default MethodVirtual"); 63 } 64 public void Method() 65 { 66 Console.WriteLine("Diamond default Method"); 67 } 68 }
语言对比:
Java——默认虚方法
默认情况下,Java中的方法都是虚方法。假如希望方法具有非虚的行为,就必须显式密封它。相反,C#的方法默认为非虚方法。
本文作者:好Wu赖
本文链接:https://www.cnblogs.com/erlongxizhu-03/p/12993830.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现