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     }
View Code

 

语言对比

Java——默认虚方法

默认情况下,Java中的方法都是虚方法。假如希望方法具有非虚的行为,就必须显式密封它。相反,C#的方法默认为非虚方法

本文作者:好Wu赖

本文链接:https://www.cnblogs.com/erlongxizhu-03/p/12993830.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   好Wu赖  阅读(1536)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起