virtual 关键字是什么?在直接进入 C# 视角之前,了解或修改面向对象编程世界中的继承、重写和虚拟关键字的概念非常重要。
方法重写是一个与继承紧密结合的 OOP 概念。当子类方法重写了具有相同名称、参数和返回类型的父类方法时,称为方法重写。 virtual 关键字向编译器表明某个方法可以在派生类中被重写。
从 C# 的角度来看,virtual 关键字用于修改任何属性、方法或事件的声明,以允许在派生类中进行重写。简单来说,virtual 关键字实现了 C# 中方法重写的概念。
语法
通过在基类中添加 virtual 关键字并在派生类中添加 override 关键字,可以覆盖任何属性、方法或事件。
在基类声明中添加virtual关键字:
public class Base { public virtual int abc { get; set; } // this property can be overridden public virtual void Xyz() { } // this method can be overridden }
在基类声明中添加 override 关键字:
public class Derived : Base { public override int abc { get; set; } // this overrides the base class property public override void Xyz() { } // this overrides the base class method }
重载和重写之间最基本的区别在于,前者是编译时机制,而后者在运行时发挥作用。 virtual 关键字在运行时起作用,从而实现了方法重写的概念。
当调用或访问任何虚拟方法或属性时,编译器会检查该方法或属性的重写成员。如果找到,就会调用它。如果没有找到,则调用原始方法或属性。
这里出现了一个很好的问题——在多级继承的情况下会发生什么?好吧,如果任何类成员在多个级别上被重写,则会调用最深的重写成员(最深的派生类中的成员)。
下面提到了 C# 中的虚拟关键字的示例
让我们举个例子来了解当单个子类继承父类时,即没有多级继承时,virtual 关键字的工作原理。
代码:
using System; public class Polynomial { public virtual double len { get; set; } public virtual double wid { get; set; } public virtual double Area() { return len * wid; } } public class Rectangle: Polynomial { } public class Square : Polynomial { public override double len { get; set; } public override double Area() { return len * len; } } public class Circle : Polynomial { public double radius { get; set; } public override double Area() { return Math.PI * radius * radius; } } public class Triangle : Polynomial { public override double Area() { return 0.5 * len * wid; } } public class Program { public static void Main() { var rect = new Rectangle(); rect.len = 5; rect.wid = 10; Console.WriteLine("Area of Rectangle = " + rect.Area()); var sq = new Square(); sq.len = 15; Console.WriteLine("Area of Square = " + sq.Area()); var cir = new Circle(); cir.radius = 10; Console.WriteLine("Area of Circle = " + cir.Area()); var tri = new Triangle(); tri.len = 5; tri.wid = 10; Console.WriteLine("Area of Triangle = " + tri.Area()); } }
输出:
在基类 Polynomial 中,我们将两个属性和一个方法声明为 virtual。现在可以在子类中覆盖这些。现在我们创建继承 Polynomial 类的各种不同形状的子类。
在 Rectangle 类中,我们不需要重写任何属性或方法。基类实现将按原样用于 Rectangle 类。
在 Square 类中,我们没有 width 属性。因此,我们重写 length 属性和 Area 方法以返回长度的平方。
在 Circle 类中,我们既没有长度也没有宽度。因此,我们声明一个新的类特定属性 radius 并相应地重写 Area 方法。
在 Triangle 类中,我们只需重写 Area 方法,属性继承自基类 Polynomial。
当我们创建派生类的对象时,编译器在基类构造过程中遇到 virtual 关键字,从而查找重写的成员。然后相应地调用被覆盖的成员。
让我们修改上面的示例以包含多级继承。
代码:
using System; public class Polynomial { public virtual double len { get; set; } public virtual double wid { get; set; } public virtual double Area() { return 0; } } public class Rectangle : Polynomial { public override double Area() { return len * wid; } } public class Square : Rectangle { public override double len { get; set; } public override double Area() { return len * len; } } public class Program { public static void Main() { var rect = new Rectangle(); rect.len = 5; rect.wid = 10; Console.WriteLine("Area of Rectangle = " + rect.Area()); var sq = new Square(); sq.len = 15; Console.WriteLine("Area of Square = " + sq.Area()); } }
输出:
虚拟成员在基类和派生类中都有声明和定义。当派生类中需要一些额外的功能时,虚拟成员是有利的。它们作为附加组件。
在这篇文章中,我们了解了 C# 中虚拟的概念。我们了解了 C# 如何在运行时实现 virtual 关键字并查看了示例。
虚拟成员是面向对象编程的一个伟大概念。然而,为了获得深入的知识,强烈建议学习abstract关键字、interfaces和new关键字。这将极大地有助于理解它们之间的区别。这有助于了解何时使用和何时不使用虚拟。
以上是C# 中的虚拟关键字 的详细内容。更多信息请关注PHP中文网其他相关文章!