几行代码搞懂C#中的虚方法

链接: 源码
在C#中,虚方法(virtual method)是一种特殊的方法,它允许派生类(子类)重写(override)该方法的实现。在C#中,虚方法(virtual method)是面向对象编程中的一个重要概念,它允许子类重写父类中的方法。当子类对象调用这个方法时,将执行子类中的重写版本,而不是父类中的原始版本.虚方法的主要目的是实现多态性,即允许基类的对象根据其实际类型(而不是其声明类型)来执行不同的行为。

下面是一个简单的例子来说明虚方法的使用:

// 基类
public class Animal
{
    //普通方法
    public void Walk() 
    {
        Console.WriteLine("该动物在走路");
    }
    // 虚方法
    public virtual void MakeSound()
    {
        Console.WriteLine("The animal makes a sound");
    }
}


// 派生类
 public class Dog : Animal
 {
     public void Walk()
     {
         Console.WriteLine("小狗在走路");
     }
     // 重写虚方法
     public override void MakeSound()
     {
         Console.WriteLine("The dog barks");
     }
 }


// 派生类
public class Cat : Animal
{
    //普通方法
    public new void Walk() //虽然名字与基类的方法一致,但该方法与基类没有关系
    {
        Console.WriteLine("小猫在走路");
    }
    // 重写虚方法
    //public override void MakeSound()
    //{
    //    Console.WriteLine("The cat meows");
    //}
}

// 主程序
class Program
{
    static void Main(string[] args)
    {
        Animal animal1 = new Dog(); // Dog对象,但引用类型为Animal
        Animal animal2 = new Cat(); // Cat对象,但引用类型为Animal

        animal1.MakeSound(); // 输出 "The dog barks"
        animal2.MakeSound(); // 输出 "The cat meows"
    }
}

解析:

基类 Animal:

  1. 普通方法 Walk(): 这是一个非虚(non-virtual)方法,直接定义了动物走路的行为,输出“该动物在走路”。

  2. 虚方法 MakeSound(): 这是一个虚方法(marked with the virtual keyword),它提供了动物发出声音的基本行为,默认输出“ The animal makes a sound”。虚方法允许派生类对其进行重写(override),提供特定于派生类的声音表现。

派生类 Dog:

  1. 重写 Walk() 方法: 在 Dog 类中,Walk() 方法被重定义,并使用 override 关键字明确指出它正在覆盖基类 Animal 中的同名虚方法。因此,当对 Dog 类型的对象调用 Walk() 时,将执行派生类中的实现,输出“小狗在走路”。

  2. 重写 MakeSound() 方法: 同样地,Dog 类重写了 MakeSound() 虚方法,提供狗特有的叫声表现,输出“ The dog barks”。

派生类 Cat:

  1. 隐藏 Walk() 方法: Cat 类也重新定义了 Walk() 方法,但这里使用的是 new 关键字而非 override。这意味着尽管方法名称与基类中的相同,但这个新方法与基类的 Walk() 没有继承关系,而是创建了一个新的独立方法,称为隐藏(hiding)。当对 Cat 类型的对象调用 Walk() 时,会执行派生类中的实现,输出“小猫在走路”。然而,如果通过一个 Animal 类型的引用(实际指向 Cat 对象)调用 Walk(),由于没有重写基类方法,仍将执行基类 AnimalWalk() 实现。

  2. 注释掉的 MakeSound() 方法: 在提供的代码中,Cat 类的 MakeSound() 方法被注释掉了。若取消注释,则它会按照 Dog 类的方式,重写 Animal 中的 MakeSound() 虚方法,提供猫特有的叫声表现(“The cat meows”)。由于当前注释状态,Cat 类并未提供自己的 MakeSound() 实现,所以默认情况下会继承并使用基类 Animal 中的 MakeSound() 方法。

总结一下:

  • Dog 类通过 override 重写了基类 Animal 的两个方法:Walk()MakeSound(),提供了狗特有的行为表现。
  • Cat 类使用 new 关键字隐藏了基类的 Walk() 方法,提供了猫特有的走路行为。但未重写 MakeSound() 方法,故仍使用基类的实现。

注意,对于方法的重写(override)和隐藏(使用 new 关键字),两者在多态性和继承行为上有所不同:

  • 重写(Override):保持了多态性,即通过父类引用调用子类对象的方法时,会调用子类的重写实现。
  • 隐藏(New):破坏了多态性,通过父类引用调用子类对象的方法时,调用的是父类的方法。只有通过子类本身的引用调用时,才会执行隐藏的新方法。

注意:

  1. 如果一个方法在基类中被声明为 virtual,那么任何派生类都可以使用 override 关键字来重写该方法。
  2. 如果一个方法在基类中被声明为 override,那么在派生类中不能再次重写它。但是,你可以在派生类中调用基类的实现(使用 base.MethodName())。
  3. 如果一个方法没有被声明为 virtual,那么它就是非虚方法,派生类不能重写它。尝试这样做会导致编译错误。
  4. 虚方法可以有访问修饰符(如 publicprotectedprivate),以及其他的修饰符(如 staticabstractsealed)。但是,一个方法不能同时是 virtualstatic,也不能同时是 virtualabstract(尽管 abstract 方法隐式地是虚的)。

英语

单词音标解释例句难点单词拓展
virtual/ˈvɜːtʃuəl/adj. (通过计算机软件,如在互联网上)模拟的,虚拟的;几乎…的;实际上的;事实上的;实质上的;很接近的1) The country was sliding into a state of virtual civil war. 2) players can compete in a virtual world of role playing…
retrieve/rɪˈtriːv/vt. 检索;取回;检索数据;找回;挽回;索回;扭转颓势 n. 恢复 记忆 re- 重新 + -trieve 找She bent to retrieve her comb from the floor.
derive/dɪˈraɪv/v. 得到;获得;(使)产生;取得;(使)起源 记忆 de- 离开,向下 + riv- 河流,流动 + -e1) Anna’s strength is derived from her parents and her sisters. 2) He derived great pleasure from painting.
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值