当我们在派生类中重写基类的同名函数时,若基类指针或引用指向派生类对象,这时若基类函数被调用,会调用派生类中的函数而不是基类中的函数。但是,如果将基类指针或引用指向派生类对象的实例时,如果使用基类指针或引用来访问这个函数,则只会调用基类中的函数,而不会调用派生类中的函数。为了解决这个问题,C#中引入了虚函数virtual的机制。
虚函数用来实现多态,将基类中的函数在派生类中标记为virtual,如果派生类中实现了相同的虚函数,则在通过基类指针或引用调用该虚函数时会调用派生类中的虚函数。如果在派生类中未实现该虚函数,则调用基类中的虚函数。
C#中的虚函数定义方式为:
public virtual 返回类型 函数名称(参数列表)
{
// 函数体
}
下面是两条示例说明:
示例1
public class Shape
{
public virtual int Area()
{
return 0;
}
}
public class Rectangle : Shape
{
int length;
int width;
public Rectangle(int length, int width)
{
this.length = length;
this.width = width;
}
public override int Area()
{
return length * width;
}
}
public class Circle : Shape
{
int radius;
public Circle(int radius)
{
this.radius = radius;
}
public override int Area()
{
return (int)(Math.PI * Math.Pow(radius, 2));
}
}
public class Test
{
public static void Main(string[] args)
{
Shape[] shapes = new Shape[] { new Rectangle(3, 4), new Circle(5) };
for (int i = 0; i < shapes.Length; i++)
{
Console.WriteLine("Area of shape[{0}] = {1}", i, shapes[i].Area());
}
}
}
输出结果为:
Area of shape[0] = 12
Area of shape[1] = 78
在这个例子中,我们定义了一个Shape类,其中包含一个Area函数,但这个函数没有任何实现。我们还定义了两个继承自Shape类的派生类,分别是Rectangle和Circle,并且在这两个类中实现了Area函数。在Test类中,我们创建了两个Shape类型数组的实例,并分别调用了其Area函数。由于Area函数被标记为virtual,所以当我们在数组中迭代时,会调用它相应派生类中的实现程序。
示例2
public class Employee
{
public virtual void PrintName()
{
Console.WriteLine("Employee");
}
}
public class Manager : Employee
{
public override void PrintName()
{
Console.WriteLine("Manager");
}
}
public class Test
{
public static void Main(string[] args)
{
Employee e = new Employee();
Employee m = new Manager();
e.PrintName(); // 输出:Employee
m.PrintName(); // 输出:Manager
}
}
在这个例子中,我们定义了两个类,Employee和Manager,其中Manager继承自Employee类,并且覆盖了函数PrintName。在Test类中,我们分别创建了Employee和Manager的实例,并分别调用了它们的PrintName函数。由于PrintName被标记为virtual,调用Manager实例上的PrintName函数时,会调用Manager类中的PrintName实现程序。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#中的虚函数virtual - Python技术站