C# 中虚函数和抽象函数的区别

2025年2月5日 | 阅读5分钟

本文将讨论 C# 中虚函数和抽象函数的区别。在此之前,让我们先理解每个术语。

什么是虚函数?

虚方法是面向对象编程的一个基本概念。它们允许在派生类中使用相同签名的任何方法来覆盖其行为。继承是可选的,派生类不一定需要复制基类的行为。默认情况下,方法是非虚的,不能被覆盖。我们通过在方法签名开头、返回类型之后添加 virtual 关键字来引入虚方法。它们可以有返回类型,也可以没有。

当方法是以下情况时,我们不能使用 virtual 关键字:

  • 静态的
  • 抽象的
  • 是构造函数/函数或 getter/setter 对。

通过从父类调用虚方法设置的多态性将被覆盖。

示例

让我们举一个例子来说明 C# 中的虚函数

输出

 
Drawing the shapes
Drawing the square
Drawing the cube   

说明

在此示例中,此代码展示了如何在 C# 中使用虚函数。Art 类有一个名为Drawing()的虚函数,具有默认函数 Print ("Drawing the shapes")。Square 类和 Cube 类都派生自 Art,因此需要实现它们各自的 Drawing() 函数版本。在 Main 方法中,创建了 Art 类的实例对象,并对每个对象调用了 Drawing() 函数。输出将是:“Draw shapes”(绘制图形),“Draw a square”(绘制正方形),以及“Draw a cube”(绘制立方体)。

什么是抽象函数?

抽象方法是在基类中声明为抽象的方法,并且不能在其中包含实现,这意味着它们不能包含任何主体或功能。当希望方法在其所属类型的类中显式覆盖其实现时,可以使用抽象方法。它定义了编译器在何时检查代码中发生的任何错误。在这种情况下,如果基类有一个用 abstract 修饰符声明的抽象方法,那么该类的所有子类都必须实现该抽象方法;否则,编译器将显示一个错误,指示派生类尚未实现抽象成员。具体来说,抽象方法是在抽象基类中使用 abstract 关键字声明的,而该类型的非抽象子类应具有其抽象方法的实现。

抽象方法是否是虚方法并不明确,但我们在声明抽象方法时应避免使用 virtual 关键字。与其他方法不同,抽象方法只能在抽象类中声明。抽象方法的应用示例包括强制覆盖 ToString() 或 equals() 方法。

示例

让我们举一个例子来说明 C# 中的抽象函数

输出

 
Drawing the square
Drawing the cube   

说明

本程序显示了 C# 中抽象函数的示例。Art 类被声明为一个抽象类,其中包含一个名为 Drawing() 的抽象函数。Art 类中的 Drawing() 函数被子类 Cube 继承,并且 Drawing() 函数被子类 Cube 继承。它被重写以提供它们各自的实现。在 Main 函数中,创建了 Square 和 Cube 的实例,并对每个对象调用了 Drawing 函数。生成的输出将是“Drawing the square”(绘制正方形)或“Drawing the cube”(绘制立方体)。由于 Art 类是抽象的,因此不能直接实例化。

C# 中虚方法和抽象方法之间的主要区别

Difference between virtual and abstract functions in C#

以下是 C# 中虚函数和抽象函数之间的区别:

函数虚方法抽象方法
声明使用名为“virtual”的关键字在虚拟基类中定义虚方法。必须使用人工语言声明格式在抽象类或接口中指定。
方法体它表示基类中的实现,根据派生类的性质,可以编辑或替换。它通常从底层类继承。它们没有任何内置类。
可选覆盖可以使用 override 关键字在派生类中重新定义虚函数。抽象方法需要在子类中被覆盖,并强制使用“override”符号。
后期绑定继承在运行时动态实现。这种动态分派机制根据运行时对象类型决定应执行所有相关方法中的哪一个。已解决的选项是指解决方案将在编译时执行(静态分派)还是在运行时执行(动态分派)。它在编译时得到解决。
默认行为如果基类未在派生类中定义,则自动使用继承修饰符。由于基类没有定义任何默认行为,因此没有实现。
多态它实现了多态性,有助于跟踪具有不同类作为其派生类型的对象,并将它们作为基类对象进行处理。它提供了多态性,使派生类实现此接口,同时强制定义适当的功能。
类类型它可以在非抽象类或抽象类中使用。抽象函数可以在抽象类和接口中定义,这两者都是抽象的。
类实例化展示可以用来说明产品类价值提供者的作用。继承提供了灵活性,因为一个人不能直接创建随机抽象类(抽象类),而只能用作具体类的基类(具体类)。
多重继承它不包含多重继承。它包含多重继承。
实现数量通过定义不同的派生类,可以将其更改为不同的实现。没有派生类,最终用户无法使用它。

结论

在 C# 中,虚方法通过基类提供默认实现,允许派生类选择性地覆盖以实现运行时多态。抽象方法必须在抽象类/接口中声明,它强制子类实现,而没有默认行为。它们使接口更易于理解,并有助于编写一致且可扩展的代码。虚拟技术为客户端提供了定义自己方法的可能性,而抽象方法则是强制性的,为继承过程增加了结构。