C# 虚方法virtual详解

C# 虚方法virtual详解

virtual 关键字用于声明一个虚方法,可以在派生类中被重写(override)。虚方法允许基类定义一个方法的默认实现,但允许派生类提供自己的实现。

  1. 1. 声明虚方法:在基类中,使用 virtual 关键字声明一个方法,表示该方法可以在派生类中被重写。

public class BaseClass
{
   public virtual void Display()
   {
    Console.WriteLine("Display method of BaseClass");
   }
}
  1. 重写虚方法:在派生类中,使用 override 关键字来重写基类中的虚方法。

public class DerivedClass : BaseClass
{
   public override void Display()
   {
      Console.WriteLine("Display method of DerivedClass");
   }
}
  1. 3. 调用虚方法:当你调用一个对象的虚方法时,实际调用的方法取决于对象的运行时类型,即使对象是作为基类类型引用的。

BaseClass obj = new DerivedClass();
  obj.Display(); // 输出 "Display method of DerivedClass"
  1. 4. 调用基类的虚方法:在派生类的重写方法中,可以使用 base 关键字调用基类的实现。

public override void Display()
{
    base.Display(); // 调用基类的 Display 方法
    Console.WriteLine("Additional functionality in DerivedClass");
}
  1. 5. 密封方法:如果不想允许进一步的派生类重写某个方法,可以使用 sealed 关键字。

public class BaseClass
{
    public virtual void Method()
    {
        // ...
    }
}

public class DerivedClass : BaseClass
{
    public sealed override void Method()
    {
        // 其他派生类不能重写这个方法
    }
}
  1. 6. 抽象类和虚方法:抽象类可以包含虚方法,但抽象类本身不能被实例化。

public abstract class AbstractClass
{
  public virtual void Method() { }
  public abstract void AnotherMethod();
}
  1. 7. 虚属性和索引器:除了方法,C# 还允许属性和索引器是虚的。

  2. 8. 多态性:虚方法是实现多态性的一种方式。多态性允许你编写通用的代码,该代码可以操作不同类型的对象,而具体使用哪个对象的实现则在运行时确定。

示例

override是重写 overload是重载

//示例转自:https://www.cnblogs.com/zhaoshujie/p/10502404.html
using System;

namespace VirtualMethodTest
{
    class A
    {
        public virtual void Func() // 注意virtual,表明这是一个虚拟函数
        {
            Console.WriteLine("Func In A");
        }
    }

    class B : A // 注意B是从A类继承,所以A是父类,B是子类
    {
        public override void Func() // 注意override ,表明重新实现了虚函数
        {
            Console.WriteLine("Func In B");
        }
    }

    class C : B // 注意C是从A类继承,所以B是父类,C是子类
    {
    }

    class D : A // 注意B是从A类继承,所以A是父类,D是子类
    {
        public new void Func() // 注意new ,表明覆盖父类里的同名类,而不是重新实现
        {
            Console.WriteLine("Func In D");
        }
    }

    class program
    {
        static void Main()
        {
            A a = new A(); // 实例化a对象,A是a的实例类
            A b= new B(); // 实例化b对象,B是b的实例类
            A c = new C(); // 实例化b对象,C是b的实例类
            A d= new D(); // 实例化b对象,D是b的实例类

  
            a.Func();    // 执行a.Func:1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类A,就为本身 4.执行实例类A中的方法 5.输出结果 Func In A
            b.Func();    // 执行b.Func:1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类B,有重载的 4.执行实例类B中的方法 5.输出结果 Func In B
            c.Func();    // 执行c.Func:1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类C,无重载的 4.转去检查类C的父类B,有重载的 5.执行父类B中的Func方法 5.输出结果 Func In B
            d.Func();    // 执行d.Func:1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类D,无重载的(这个地方要注意了,虽然D里有实现Func(),但没有使用override关键字,所以不会被认为是重载) 4.转去检查类D的父类A,就为本身 5.执行父类A中的Func方法 5.输出结果 Func In A
            D d1 = new D();
            d1.Func(); // 执行D类里的Func(),输出结果 Func In D
            Console.ReadLine();
        }
    }
}

欢迎关注我的公众号Net分享

推荐阅读

-看看这样的Dotnet后台管理,那真是叫一个清新优雅高颜值!!!-点我查看

  • • 体验地址:https://malus.dotnetshare.com

    f8510c0fa9fe0fc44893ee489ce1d0b8.jpeg
5758b397c7195d838f9d8fe342abb229.jpeg66826a81430d23414d62ed87f468e3a4.jpeg
1733caf74558c9960c35ec82ef53e1d4.jpegdde9cb8b80edd956cad46114364e09f2.jpeg
55908e89665ab170f8048556196b2fc5.jpeg5f1265619a779322cd500aad8b7d3032.jpeg
6d3f4ee2b08ef69798cdca137780b057.jpeg98fa96080985bac7673ed428cf73c237.jpeg
edca6d6c05ff94c3d7a3cf091a50048e.jpeg70f0dbc9ced243a84765d344b49d8a55.jpeg
db1a07bf43ee94ea4eacbb5e29f07617.jpegc066d9753807b633fbb974425452b3d4.jpeg
6459d5f0412e3882d16e26770cfe8180.jpeg2a981d262cdb6fb4c959220e94fc0808.jpeg
c260a110bb16a89b8fe3d3aa244521ca.jpegfa91d86fba69857594fc0bcb22a3f238.jpeg

-超级漂亮干净的Dotnet学习网站

  • • 体验地址:https://www.dotnetshare.com

    8e92e2c01f972366ae7f843c21e9344a.png
加我微信,拉你进全栈进阶、面试交流群,互相监督学习进步等!


❤️ 看完三件事如果你觉得这篇内容对你挺有启发,我想邀请你帮个小忙:
点个「在看」,让更多的人也能看到这篇内容 
关注公众号「NetShare」,持续为你推送精选好文 
点一下,代码无 Bug
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中,virtual关键字用于修饰基类的方法、属性、索引器或事件声明。被virtual修饰的方法、属性、索引器或事件是可以在派生类中重写的,也就是可以进行修改。虚方法是指被virtual关键字修饰的基类实例方法,需要在派生类中进行重写和修改。重写方法需要使用override关键字声明,表示覆盖基类的方法。派生类重写的方法的签名和返回值类型必须与基类的相同。如果基类的方法被virtual修饰,但派生类在重写时没有使用override关键字修饰,会发出警告。如果派生类没有重写基类的方法,只是继承了该方法,那么调用派生类的这个方法时,输出的结果肯定是基类的。virtual修饰符不能与static、abstract、private和override关键字一起使用。在C#中,虚拟函数是在运行时根据对象实例动态判断要调用的函数,而一般函数在编译时就静态地编译到执行文件中。调用一个对象的函数时,系统会检查该对象申明定义的类,看所调用的函数是否为虚函数。如果是虚函数,系统会根据对象的实例类来判断要调用的函数,如果实例类中有重新实现该虚函数的方法,则执行该方法,否则会沿着父类链继续寻找重载了该虚函数的父类,并执行重载后的函数。 #### 引用[.reference_title] - *1* *2* [C#关键字——virtual浅见](https://blog.csdn.net/abraham_ly/article/details/106721488)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [C# 虚方法virtual详解](https://blog.csdn.net/m0_65636467/article/details/128797283)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值