虚方法和重写方法的继承特性
这个题目起的还是有点不合适,但是当你看到下面的代码就会明白我在搞些什么名堂,其实质是辨析了一下virtual关键字和override关键字,MD写的代码,部分语言输入法兼容性问题,搞的我只能用用英文注释,破键盘这两也让我敲坏了很多键都按下了不起作用了,无奈啊。。。。下面我按我的理解简单的介绍一下虚方法和重写方法。
虚方法:这个方法其实就是为了重写方法而存在的(在声明中包含virtual关键字),否则哪,我也没感觉它存在的意义。
其一:因为要重写所以它的访问类型如果为private则毫无意义阻碍了重写动作的进行也就是它不能私有化,所以C#中virtual关键字和private关键字不能同时使用。
其二:因为静态的方法和抽象方法不能重写,同理C#中static,abstract关键字和virtual关键字不能同时使用。
其三:不能在声明虚方法的同时指定重写虚方法,因为重写方法只能重写基类的虚方法,也就是要提前在基类中声明虚方法,所以virtual关键字和override关键字不能同时使用。
重写方法:就是使从基类继承的虚方法提供新的实现(使用关键字override声明),从而为其子类所专有化。
同上面的思路一样:因为静态的方法和抽象方法不能重写,同理C#中static,abstract,new关键字和override关键字不能同时使用。
今天彻底的实验了一下,总结用法如下:
非虚方法的实现(全部隐藏的虚方法)最初声明的是什么类的方法就永远是什么类的方法。
虚方法的实现:最终是什么类型的方法就调用该类型的方法。
(含有隐藏的)虚方法的实现:最终是什么类型的方法就调用(最靠近)该类型的方法。
直接上代码,看看就明白了我总结的用法了。
using System;
namespace HideTest
{
class Great_grandfather
{
public void printf()
{
Console.WriteLine("曾祖父.printf()");
}//非虚方法
public virtual void F()
{
Console.WriteLine("曾祖父.F()");
}//虚方法
public virtual void D()
{
Console.WriteLine("曾祖父.D()");
}//虚方法
public virtual void E()
{
Console.WriteLine("曾祖父.E()");
}
}
class grandfather:Great_grandfather
{
new private void printf() //仅在grandfather类内隐藏Great_grandfather.printf()方法
{
Console.WriteLine("祖父.printf()");
}
public void Show()
{
grandfather n=new grandfather();
n.printf();
}
new public virtual void F()
{
Console.WriteLine("祖父.F()");
}
public override void D()
{
Console.WriteLine("祖父.D()");
}
public override void E()
{
Console.WriteLine("祖父.E()");
}
}
class father_1:grandfather
{
new public void printf()
{
Console.WriteLine("父.printf()");
}
new public virtual void F()
{
Console.WriteLine("父.F()");
}
new public virtual void D()//Hide The base class methods, Redefined a new method.
{
Console.WriteLine("父.D()");
}
public override void E()
{
Console.WriteLine("父.E()");
}
}
class father_2 : grandfather
{
public void TryHide()
{
father_2 father = new father_2();
father.printf();
}
}
class child:father_1
{
new public void printf()
{
Console.WriteLine("子.printf()");
}
new public virtual void F()
{
Console.WriteLine("子.F()");
}
public override void D()
{
Console.WriteLine("子.D()");
}
public override void E()
{
Console.WriteLine("子.E()");
}
}
class Test
{
public static void Main()
{
child a = new child();
father_1 b = a;
grandfather c = a;
Great_grandfather d = a;
father_2 e = new father_2();
Console.WriteLine("=========test the inherited of methods===========\n\n");
Console.WriteLine("=========测试隐藏非虚方法===========");
a.printf(); //调用child.printf(),打印子.printf()
b.printf(); //调用father.printf(),打印父.printf()
e.printf(); //此处证明仅在grandfather类内隐藏了Great_grandfather.printf()方法
//所以此处仍调用Great_grandfather.printf()
c.printf(); //因为father.printf()在grandfather类外不可见( 注意和e.printf()的区别)
//所以仍调用继承的Great_grandfather.printf()的方法
c.Show(); //在grandfather类内隐藏了Great_grandfather.printf()的方法在打印祖父.printf()
d.printf();//调用 Great_grandfather.printf()打印曾祖父.printf()
Console.WriteLine("=========测试(隐藏的)隐藏虚方法===========");
a.F();//调用Child.F()
b.F();//调用father.F()
c.F();//调用grandfather.F()
d.F();//调用Great_grandfather.F()
Console.WriteLine("=========测试重写(含隐藏的)虚方法===========");
a.D();//调用Child.D()
b.D();//调用Child.D() override by the Chid.D()
c.D();//调用grandfather.D() because it is Hide in the (farther)class not override
d.D();//调用grandfather.D() override by the grandfather.D()
Console.WriteLine("=========测试重写(不含隐藏的)虚方法===========");
a.E();//调用Child.E()
b.E();//调用Child.E()
c.E();//调用Child.E()
d.E();//调用Child.E()
Console.WriteLine("=========OVER===========");
Console.ReadKey();
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?